

/*++

Copyright (c) 1998-2002 Microsoft Corporation

Module Name:

    Http.h

Abstract:

    This header corresponds to the HTTP API specification

Revision History:

--*/


#ifndef __HTTP_H__
#define __HTTP_H__

#pragma once
#include <winapifamily.h>

#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)


#if _WIN32_WINNT >= 0x0501

//
// HTTPAPI is available on
//
// a) WinXP SP2 and higher
// b) Windows 2003 and higher
// c) Vista and higher.
//


#include <winsock2.h>
#include <ws2tcpip.h>


#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus


//
// Flags for HttpInitialize() and HttpTerminate().
//
//
// HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for
//                          applications using server APIs.
//
// HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for
//                          applications using HTTP configuration APIs.
//
// HTTP_DEMAND_CBT        - Pre-Win7, it checks HTTP API layer and driver for
//                          Extended Protection capabilities.
//                          On Win7 and above, this flag has no use and is
//                          present only for app-compat reasons.
//                          It must be combined with HTTP_INITIALIZE_SERVER.
//
// Notes -
//
// 1. These flags can be used in combination.
//
// 2. HttpTerminate() must be called for each call to HttpInitialize() made
//    with each flag set when invoking HttpInitialize.  For example, one
//    could make two calls to HttpInitialize() setting HTTP_INITIALIZE_SERVER
//    the first time and HTTP_INITIALIZE_CONFIG the second time.  One call
//    to HttpTerminate() with both flags set suffices to clean up both
//    calls to HttpInitialize().
//

#define HTTP_INITIALIZE_SERVER          0x00000001
#define HTTP_INITIALIZE_CONFIG          0x00000002
#define HTTP_DEMAND_CBT                 0x00000004


#if _WIN32_WINNT >= 0x0600

//
// Following section defines the properties supported by the
// server side HTTP API.
//

typedef enum _HTTP_SERVER_PROPERTY
{
    //
    // Used for enabling server side authentication.
    //

    HttpServerAuthenticationProperty = 0,

    //
    // Used for enabling logging.
    //

    HttpServerLoggingProperty = 1,

    //
    // Used for setting QoS properties.
    //

    HttpServerQosProperty = 2,

    //
    // Used for configuring timeouts.
    //

    HttpServerTimeoutsProperty = 3,

    //
    // Used for limiting request queue lengths.
    //

    HttpServerQueueLengthProperty = 4,

    //
    // Used for manipulating the state.
    //

    HttpServerStateProperty = 5,

    //
    // Used for modifying the verbosity level of 503 type responses
    // generated by server side API.
    //

    HttpServer503VerbosityProperty = 6,

    //
    // Used for manipulating Url Group to Request Queue association.
    //

    HttpServerBindingProperty = 7,

    //
    // Extended authentication property.
    //

    HttpServerExtendedAuthenticationProperty = 8,

    //
    // Listening endpoint property.
    //

    HttpServerListenEndpointProperty = 9,

    //
    // Authentication channel binding property
    //

    HttpServerChannelBindProperty = 10,

    //
    // IP Protection level policy for a Url Group.
    //

    HttpServerProtectionLevelProperty = 11,


    //
    // Used for manipulating Url Group to Delegate Request Queue association.
    //

    HttpServerDelegationProperty = 16,


    //
    // Used to configure fast forwarding support.
    //

    HttpServerFastForwardingProperty = 18

} HTTP_SERVER_PROPERTY, *PHTTP_SERVER_PROPERTY;


#define HTTP_MAX_SERVER_QUEUE_LENGTH    0x7FFFFFFF
#define HTTP_MIN_SERVER_QUEUE_LENGTH    1

//
// Generic property flags. Each structure defining a property info typically
// contain an element of this type.
//

typedef struct _HTTP_PROPERTY_FLAGS
{
    ULONG Present:1;

} HTTP_PROPERTY_FLAGS, *PHTTP_PROPERTY_FLAGS;

//
// Enabled state.
//

typedef enum _HTTP_ENABLED_STATE
{
    HttpEnabledStateActive,
    HttpEnabledStateInactive,

} HTTP_ENABLED_STATE, *PHTTP_ENABLED_STATE;


typedef struct _HTTP_STATE_INFO
{
    HTTP_PROPERTY_FLAGS Flags;
    HTTP_ENABLED_STATE  State;

} HTTP_STATE_INFO, *PHTTP_STATE_INFO;

//
// Defines the verbosity level for a request queue which will be used
// when sending "503 - Service Unavailable" type error responses. Note that
// this setting only affects the error responses generated internally
// by HTTPAPI.
//

typedef enum _HTTP_503_RESPONSE_VERBOSITY
{
    //
    // Instead of sending a 503 response, the connection will be reset.
    // This is the default behavior.
    //
    Http503ResponseVerbosityBasic,

    //
    // Will send a 503 w/ a generic reason phrase.
    //
    Http503ResponseVerbosityLimited,

    //
    // Will send a 503 w/ a detailed reason phrase.
    //
    Http503ResponseVerbosityFull

} HTTP_503_RESPONSE_VERBOSITY, *PHTTP_503_RESPONSE_VERBOSITY;

//
// Network QoS related.
//

typedef enum _HTTP_QOS_SETTING_TYPE
{
    HttpQosSettingTypeBandwidth,
    HttpQosSettingTypeConnectionLimit,
    HttpQosSettingTypeFlowRate

} HTTP_QOS_SETTING_TYPE, *PHTTP_QOS_SETTING_TYPE;

typedef struct _HTTP_QOS_SETTING_INFO
{
    HTTP_QOS_SETTING_TYPE QosType;
    PVOID QosSetting;
} HTTP_QOS_SETTING_INFO, *PHTTP_QOS_SETTING_INFO;

typedef struct _HTTP_CONNECTION_LIMIT_INFO
{
    HTTP_PROPERTY_FLAGS Flags;
    ULONG MaxConnections;

} HTTP_CONNECTION_LIMIT_INFO, *PHTTP_CONNECTION_LIMIT_INFO;

typedef struct _HTTP_BANDWIDTH_LIMIT_INFO
{
    HTTP_PROPERTY_FLAGS Flags;
    ULONG MaxBandwidth;

} HTTP_BANDWIDTH_LIMIT_INFO, *PHTTP_BANDWIDTH_LIMIT_INFO;

typedef struct _HTTP_FLOWRATE_INFO
{
    HTTP_PROPERTY_FLAGS Flags;
    ULONG MaxBandwidth;
    ULONG MaxPeakBandwidth;
    ULONG BurstSize;

} HTTP_FLOWRATE_INFO, *PHTTP_FLOWRATE_INFO;

//
// Bandwidth throttling limit can not be set lower than the following
// number. The value is in bytes/sec.
//

#define HTTP_MIN_ALLOWED_BANDWIDTH_THROTTLING_RATE ((ULONG)1024)

//
// Distinguished value for bandwidth, connection limits and logging rollover
// size indicating "no limit".
//

#define HTTP_LIMIT_INFINITE   ((ULONG)-1)

//
// Timeout information.
//

//
// For manipulating global timeout settings.
// These timers run when connection does not belong to any application.
// Value zero is not allowed for driver wide timeout settings.
//

typedef enum _HTTP_SERVICE_CONFIG_TIMEOUT_KEY
{
    IdleConnectionTimeout = 0,
    HeaderWaitTimeout

} HTTP_SERVICE_CONFIG_TIMEOUT_KEY, *PHTTP_SERVICE_CONFIG_TIMEOUT_KEY;

typedef USHORT HTTP_SERVICE_CONFIG_TIMEOUT_PARAM,
               *PHTTP_SERVICE_CONFIG_TIMEOUT_PARAM;

//
// To set a timeout value use the set structure. To query/delete use the key
// directly. When you query a timeout value the output buffer must be exactly
// the sizeof param.
//

typedef struct _HTTP_SERVICE_CONFIG_TIMEOUT_SET
{
    HTTP_SERVICE_CONFIG_TIMEOUT_KEY KeyDesc;
    HTTP_SERVICE_CONFIG_TIMEOUT_PARAM ParamDesc;

} HTTP_SERVICE_CONFIG_TIMEOUT_SET, *PHTTP_SERVICE_CONFIG_TIMEOUT_SET;

//
// For manipulating application specific timeout settings.
// These timers run when there's a request being processed on a connection
// and HTTPAPI has already associated the request with an application.
// Setting a timeout value to zero will cause HTTPAPI to revert to default.
//

typedef struct _HTTP_TIMEOUT_LIMIT_INFO
{
    HTTP_PROPERTY_FLAGS Flags;

    //
    // Timeouts configured in seconds.
    //

    USHORT EntityBody;
    USHORT DrainEntityBody;
    USHORT RequestQueue;

    //
    // Following two timeouts are only enforced after first request on
    // connection is routed to the application. These will not manipulate
    // the driver wide timeouts.
    //

    USHORT IdleConnection;
    USHORT HeaderWait;

    //
    // Timeouts configured in bytes/second.
    // This timer can be turned off by setting it to MAXULONG.
    //

    ULONG MinSendRate;

} HTTP_TIMEOUT_LIMIT_INFO, *PHTTP_TIMEOUT_LIMIT_INFO;

//
//  Controls config settings
//

typedef enum _HTTP_SERVICE_CONFIG_SETTING_KEY
{
    HttpNone = 0,
    HttpTlsThrottle
} HTTP_SERVICE_CONFIG_SETTING_KEY, *PHTTP_SERVICE_CONFIG_SETTING_KEY;

typedef ULONG HTTP_SERVICE_CONFIG_SETTING_PARAM,
               *PHTTP_SERVICE_CONFIG_SETTING_PARAM;

typedef struct _HTTP_SERVICE_CONFIG_SETTING_SET
{
    HTTP_SERVICE_CONFIG_SETTING_KEY KeyDesc;
    HTTP_SERVICE_CONFIG_SETTING_PARAM ParamDesc;

} HTTP_SERVICE_CONFIG_SETTING_SET, *PHTTP_SERVICE_CONFIG_SETTING_SET;


//
// Controls whether IP-based URLs should listen on the specific IP or wildcard.
//

typedef struct _HTTP_LISTEN_ENDPOINT_INFO
{
    HTTP_PROPERTY_FLAGS Flags;

    BOOLEAN EnableSharing;

} HTTP_LISTEN_ENDPOINT_INFO, *PHTTP_LISTEN_ENDPOINT_INFO;


typedef struct _HTTP_FAST_FORWARD_INFO
{
    HTTP_PROPERTY_FLAGS Flags;
    BOOLEAN EnableFastForwarding;
} HTTP_FAST_FORWARD_INFO, *PHTTP_FAST_FORWARD_INFO;

typedef struct _HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS
{
    USHORT              DomainNameLength;
    PWSTR               DomainName;
    USHORT              RealmLength;
    PWSTR               Realm;
} HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS,
  *PHTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS;

typedef struct _HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS
{
    USHORT      RealmLength;
    PWSTR       Realm;
} HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS,
  *PHTTP_SERVER_AUTHENTICATION_BASIC_PARAMS;

//
// Definitions used for setting server side authentication property.
//

#define HTTP_AUTH_ENABLE_BASIC          (0x00000001)
#define HTTP_AUTH_ENABLE_DIGEST         (0x00000002)
#define HTTP_AUTH_ENABLE_NTLM           (0x00000004)
#define HTTP_AUTH_ENABLE_NEGOTIATE      (0x00000008)
#define HTTP_AUTH_ENABLE_KERBEROS       (0x00000010)

#define HTTP_AUTH_ENABLE_ALL             \
            (HTTP_AUTH_ENABLE_BASIC     |\
             HTTP_AUTH_ENABLE_DIGEST    |\
             HTTP_AUTH_ENABLE_NTLM      |\
             HTTP_AUTH_ENABLE_NEGOTIATE |\
             HTTP_AUTH_ENABLE_KERBEROS)


C_ASSERT(HTTP_AUTH_ENABLE_NEGOTIATE > HTTP_AUTH_ENABLE_NTLM);
C_ASSERT(HTTP_AUTH_ENABLE_NTLM > HTTP_AUTH_ENABLE_DIGEST);
C_ASSERT(HTTP_AUTH_ENABLE_DIGEST > HTTP_AUTH_ENABLE_BASIC);

#define HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING  (0x01)
#define HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL                  (0x02)

typedef struct _HTTP_SERVER_AUTHENTICATION_INFO
{
    HTTP_PROPERTY_FLAGS Flags;

    ULONG AuthSchemes;

    BOOLEAN ReceiveMutualAuth;
    BOOLEAN ReceiveContextHandle;
    BOOLEAN DisableNTLMCredentialCaching;

    UCHAR   ExFlags;

    HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS DigestParams;
    HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS  BasicParams;

} HTTP_SERVER_AUTHENTICATION_INFO, *PHTTP_SERVER_AUTHENTICATION_INFO;

#if _WIN32_WINNT >= _WIN32_WINNT_WIN7

//
// Definitions for setting authentication channel binding properties
//

typedef enum _HTTP_SERVICE_BINDING_TYPE
{
    HttpServiceBindingTypeNone = 0,
    HttpServiceBindingTypeW,
    HttpServiceBindingTypeA

} HTTP_SERVICE_BINDING_TYPE;

typedef struct _HTTP_SERVICE_BINDING_BASE
{
    HTTP_SERVICE_BINDING_TYPE Type;

} HTTP_SERVICE_BINDING_BASE, *PHTTP_SERVICE_BINDING_BASE;

typedef struct _HTTP_SERVICE_BINDING_A
{
    HTTP_SERVICE_BINDING_BASE Base;
    PCHAR Buffer;
    ULONG BufferSize;

} HTTP_SERVICE_BINDING_A, *PHTTP_SERVICE_BINDING_A;

typedef struct _HTTP_SERVICE_BINDING_W
{
    HTTP_SERVICE_BINDING_BASE Base;
    PWCHAR Buffer;
    ULONG BufferSize;

} HTTP_SERVICE_BINDING_W, *PHTTP_SERVICE_BINDING_W;

typedef enum _HTTP_AUTHENTICATION_HARDENING_LEVELS
{
    HttpAuthenticationHardeningLegacy = 0,
    HttpAuthenticationHardeningMedium,
    HttpAuthenticationHardeningStrict

} HTTP_AUTHENTICATION_HARDENING_LEVELS;

//
// Channel binding token verification flags.
//

#define HTTP_CHANNEL_BIND_PROXY 0x1
#define HTTP_CHANNEL_BIND_PROXY_COHOSTING 0x20

//
// Service bind verification flags
//

#define HTTP_CHANNEL_BIND_NO_SERVICE_NAME_CHECK 0x2
#define HTTP_CHANNEL_BIND_DOTLESS_SERVICE 0x4

//
// Flags triggering channel bind parameters retrieval
//

#define HTTP_CHANNEL_BIND_SECURE_CHANNEL_TOKEN 0x8
#define HTTP_CHANNEL_BIND_CLIENT_SERVICE 0x10

//
// All valid flags (mask for internal checks)
//

typedef struct _HTTP_CHANNEL_BIND_INFO
{
    HTTP_AUTHENTICATION_HARDENING_LEVELS Hardening;
    ULONG Flags;
    PHTTP_SERVICE_BINDING_BASE * ServiceNames;
    ULONG NumberOfServiceNames;

} HTTP_CHANNEL_BIND_INFO, *PHTTP_CHANNEL_BIND_INFO;

typedef struct _HTTP_REQUEST_CHANNEL_BIND_STATUS
{
    PHTTP_SERVICE_BINDING_BASE ServiceName;
    PUCHAR ChannelToken;
    ULONG ChannelTokenSize;
    ULONG Flags;

} HTTP_REQUEST_CHANNEL_BIND_STATUS, *PHTTP_REQUEST_CHANNEL_BIND_STATUS;

#endif

typedef struct _HTTP_REQUEST_TOKEN_BINDING_INFO
{
    PUCHAR TokenBinding;
    ULONG TokenBindingSize;

    PUCHAR EKM;
    ULONG EKMSize;

    UCHAR KeyType;

} HTTP_REQUEST_TOKEN_BINDING_INFO, *PHTTP_REQUEST_TOKEN_BINDING_INFO;

//
// Definitions used for setting logging property.
//

//
// The known log fields recognized/supported by HTTPAPI. Following fields
// are used for W3C logging. Subset of them are also used for error
// logging.
//

#define HTTP_LOG_FIELD_DATE                 0x00000001
#define HTTP_LOG_FIELD_TIME                 0x00000002
#define HTTP_LOG_FIELD_CLIENT_IP            0x00000004
#define HTTP_LOG_FIELD_USER_NAME            0x00000008
#define HTTP_LOG_FIELD_SITE_NAME            0x00000010
#define HTTP_LOG_FIELD_COMPUTER_NAME        0x00000020
#define HTTP_LOG_FIELD_SERVER_IP            0x00000040
#define HTTP_LOG_FIELD_METHOD               0x00000080
#define HTTP_LOG_FIELD_URI_STEM             0x00000100
#define HTTP_LOG_FIELD_URI_QUERY            0x00000200
#define HTTP_LOG_FIELD_STATUS               0x00000400
#define HTTP_LOG_FIELD_WIN32_STATUS         0x00000800
#define HTTP_LOG_FIELD_BYTES_SENT           0x00001000
#define HTTP_LOG_FIELD_BYTES_RECV           0x00002000
#define HTTP_LOG_FIELD_TIME_TAKEN           0x00004000
#define HTTP_LOG_FIELD_SERVER_PORT          0x00008000
#define HTTP_LOG_FIELD_USER_AGENT           0x00010000
#define HTTP_LOG_FIELD_COOKIE               0x00020000
#define HTTP_LOG_FIELD_REFERER              0x00040000
#define HTTP_LOG_FIELD_VERSION              0x00080000
#define HTTP_LOG_FIELD_HOST                 0x00100000
#define HTTP_LOG_FIELD_SUB_STATUS           0x00200000
#define HTTP_LOG_FIELD_STREAM_ID            0x08000000
#define HTTP_LOG_FIELD_STREAM_ID_EX         0x10000000
#define HTTP_LOG_FIELD_TRANSPORT_TYPE       0x20000000

//
// Fields that are used only for error logging.
//

#define HTTP_LOG_FIELD_CLIENT_PORT          0x00400000
#define HTTP_LOG_FIELD_URI                  0x00800000
#define HTTP_LOG_FIELD_SITE_ID              0x01000000
#define HTTP_LOG_FIELD_REASON               0x02000000
#define HTTP_LOG_FIELD_QUEUE_NAME           0x04000000
#define HTTP_LOG_FIELD_CORRELATION_ID       0x40000000
#define HTTP_LOG_FIELD_FAULT_CODE           0x80000000

#define HTTP_LOG_FIELD_EXT_FAULT_CODE_EXT   0x0000000000000001

//
// Defines the logging type.
//

typedef enum _HTTP_LOGGING_TYPE
{
    HttpLoggingTypeW3C,
    HttpLoggingTypeIIS,
    HttpLoggingTypeNCSA,
    HttpLoggingTypeRaw

} HTTP_LOGGING_TYPE, *PHTTP_LOGGING_TYPE;

//
// Defines the rollover type for log files.
//

typedef enum _HTTP_LOGGING_ROLLOVER_TYPE
{
    HttpLoggingRolloverSize,
    HttpLoggingRolloverDaily,
    HttpLoggingRolloverWeekly,
    HttpLoggingRolloverMonthly,
    HttpLoggingRolloverHourly

} HTTP_LOGGING_ROLLOVER_TYPE, *PHTTP_LOGGING_ROLLOVER_TYPE;

//
// Log file rollover size can not be set lower than the following
// limit. The value is in bytes.
//

#define HTTP_MIN_ALLOWED_LOG_FILE_ROLLOVER_SIZE ((ULONG)(1 * 1024 * 1024))

//
// Logging option flags. When used in the logging configuration alters
// some default logging behaviour.
//
// HTTP_LOGGING_FLAG_LOCAL_TIME_ROLLOVER - This flag is used to change
//      the log file rollover to happen by local time based. By default
//      log file rollovers happen by GMT time.
//
// HTTP_LOGGING_FLAG_USE_UTF8_CONVERSION - When set the unicode fields
//      will be converted to UTF8 multibytes when writting to the log
//      files. When this flag is not present, the local code page
//      conversion happens.
//
// HTTP_LOGGING_FLAG_LOG_ERRORS_ONLY -
// HTTP_LOGGING_FLAG_LOG_SUCCESS_ONLY - These two flags are used to
//      to do selective logging. If neither of them are present both
//      types of requests will be logged. Only one these flags can be
//      set at a time. They are mutually exclusive.
//

#define HTTP_LOGGING_FLAG_LOCAL_TIME_ROLLOVER         (0x00000001)
#define HTTP_LOGGING_FLAG_USE_UTF8_CONVERSION         (0x00000002)
#define HTTP_LOGGING_FLAG_LOG_ERRORS_ONLY             (0x00000004)
#define HTTP_LOGGING_FLAG_LOG_SUCCESS_ONLY            (0x00000008)

//
// Configuration structure used for setting the logging property.
//

typedef struct _HTTP_LOGGING_INFO
{
    //
    // Specifies whether this property exists or not.
    //

    HTTP_PROPERTY_FLAGS Flags;

    //
    // Optional logging flags.
    //

    ULONG LoggingFlags;

    //
    // Optional informatonal software directive string for W3C type logging. Not
    // used for other types of logging. If nothing is provided here HTTPAPI will
    // log a default string. Any arbitrary string could be used here to identify
    // the application. Length cannot be greater than MAX_PATH. Lenght is in
    // bytes.
    //

    PCWSTR SoftwareName;
    USHORT SoftwareNameLength;

    //
    // Log file directory must be a fully qualified path.
    // Length must be in number of bytes.
    //

    USHORT DirectoryNameLength;
    PCWSTR DirectoryName;

    //
    // Specifies the format for the log files.
    //

    HTTP_LOGGING_TYPE Format;

    //
    // Bitmask value indicates which fields to be logged
    // if the log format is set to W3C. This must be the 'bitwise or'
    // of the HTTP_LOG_FIELD_... values.
    //

    ULONG Fields;

    //
    // Following fields are reserved they must be NULL and zero..
    //

    PVOID pExtFields;
    USHORT NumOfExtFields;

    //
    // Reserved must be zero.
    //

    USHORT MaxRecordSize;

    //
    // Defines the rollover type for the log files.
    //

    HTTP_LOGGING_ROLLOVER_TYPE RolloverType;

    //
    // Indicates the maximum size (in bytes) after which
    // the log files should be rolled over. A value of -1
    // (HTTP_LIMIT_INFINITE) indicates an unlimited size.
    // This value is discarded if rollover type is not set to
    // HttpLoggingRolloverSize.
    //

    ULONG RolloverSize;

    //
    // Specifies the security descriptor to be applied to
    // the log files and the sub-directories. If null we will
    // inherit the system default. This security descriptor must
    // be self-relative.
    //

    PSECURITY_DESCRIPTOR pSecurityDescriptor;

} HTTP_LOGGING_INFO, *PHTTP_LOGGING_INFO;

//
// Binding information.
//

typedef struct _HTTP_BINDING_INFO
{
    HTTP_PROPERTY_FLAGS Flags;
    HANDLE RequestQueueHandle;

} HTTP_BINDING_INFO, *PHTTP_BINDING_INFO;

#endif
#if _WIN32_WINNT >= _WIN32_WINNT_WIN7

//
// Defines the protection level types for UrlGroups.
//

typedef enum _HTTP_PROTECTION_LEVEL_TYPE
{
    //
    // This option will allow edge (NAT) traversed traffic, i.e. Teredo
    // for the UrlGroup, unless there is an admin rule that overwrites the
    // application's intend.
    //

    HttpProtectionLevelUnrestricted,

    //
    // This setting will ensure that edge (NAT) traversed traffic
    // will not be allowed.
    //

    HttpProtectionLevelEdgeRestricted,

    //
    // Below type is not supported by HTTP API.
    //

    HttpProtectionLevelRestricted


} HTTP_PROTECTION_LEVEL_TYPE, *PHTTP_PROTECTION_LEVEL_TYPE;

//
// Controls whether the associated UrlGroup Namespace should receive
// edge traversed traffic. By default this parameter is unspecified.
//

typedef struct _HTTP_PROTECTION_LEVEL_INFO
{
    HTTP_PROPERTY_FLAGS Flags;
    HTTP_PROTECTION_LEVEL_TYPE Level;

} HTTP_PROTECTION_LEVEL_INFO, *PHTTP_PROTECTION_LEVEL_INFO;

#endif

#if _WIN32_WINNT >= 0x0600

//
// Definitions for request queue manipulation.
//
// These flags are used with HttpCreateRequestQueue() API.
//
// HTTP_CREATE_REQUEST_QUEUE_FLAG_OPEN_EXISTING - To open an existing request
// queue. The request queue name must be supplied.
//
// HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER - Creates the request queue and
// marks that the caller process is not willing to do send/receive (HTTP I/O)on
// the handle directly.
//

#define HTTP_CREATE_REQUEST_QUEUE_FLAG_OPEN_EXISTING       (0x00000001)
#define HTTP_CREATE_REQUEST_QUEUE_FLAG_CONTROLLER          (0x00000002)
#define HTTP_CREATE_REQUEST_QUEUE_FLAG_DELEGATION          (0x00000008)

#endif // _WIN32_WINNT >= 0x0600

//
// Flags for HttpReceiveHttpRequest().
//
// HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY - Specifies that the caller would like
// any available entity body to be copied along with the protocol headers.
//
// HTTP_RECEIVE_REQUEST_FLAG_FLUSH_BODY - Specifies that the caller would like
// all of the entity bodies to be copied along with the protocol headers.
//

#define HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY         0x00000001
#define HTTP_RECEIVE_REQUEST_FLAG_FLUSH_BODY        0x00000002


#if _WIN32_WINNT >= 0x0600

//
// Flags for HttpReceiveRequestEntityBody().
//
// HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER - Specifies that the
// caller would like the buffer to get filled up with entity bodies unless
// there are no more entity bodies to be copied.
//

#define HTTP_RECEIVE_REQUEST_ENTITY_BODY_FLAG_FILL_BUFFER   0x00000001

#endif // _WIN32_WINNT >= 0x0600


//
// Flags for HttpSendHttpResponse() and HttpSendResponseEntityBody().
//
// HTTP_SEND_RESPONSE_FLAG_DISCONNECT - Specifies that the network connection
// should be disconnected immediately after sending the response, overriding
// the HTTP protocol's persistent connection features, such as
// "Connection: keep-alive".
//
// HTTP_SEND_RESPONSE_FLAG_MORE_DATA - Specifies that additional entity body
// data will be sent by the caller.
//
// HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA - Specifies that a caller wants the
// response to complete as soon as possible at the cost of buffering partial
// or the entire response.
//
// HTTP_SEND_RESPONSE_FLAG_ENABLE_NAGLING - Specifies that a caller wants to
// enable the TCP nagling algorithm for this particular send.
//
// HTTP_SEND_RESPONSE_FLAG_PROCESS_RANGES - Specifies that for a range request
// a full response content is passed and a caller wants HTTP API to process
// ranges properly.
//
// HTTP_SEND_RESPONSE_FLAG_OPAQUE - Specifies that the request/response is not
// HTTP compliant and all subsequent bytes should be treated as entity-body.
//
// HTTP_SEND_RESPONSE_FLAG_GOAWAY - A flag that must always be specified with
// HTTP_SEND_RESPONSE_FLAG_DISCONNECT. For pure HTTP/1.x connections, that is
// connections that don't do HTTP/2 and HTTP/3, this behaves the same as
// HTTP_SEND_RESPONSE_FLAG_DISCONNECT. For HTTP/2 and HTTP/3, this results in
// sending a GOAWAY frame and will cause the client to move to a different
// connection.
//
// HTTP_SEND_RESPONSE_FLAG_AUTOMATIC_CHUNKING - This flag instructs the
// http.sys to add chunk encoding automatically.
// HTTP_SEND_RESPONSE_FLAG_MORE_DATA must be specified as well. The caller
// must not add Transfer-Encoding: Chunked header.
//

#define HTTP_SEND_RESPONSE_FLAG_DISCONNECT          0x00000001
#define HTTP_SEND_RESPONSE_FLAG_MORE_DATA           0x00000002
#define HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA         0x00000004
#define HTTP_SEND_RESPONSE_FLAG_ENABLE_NAGLING      0x00000008
#define HTTP_SEND_RESPONSE_FLAG_PROCESS_RANGES      0x00000020
#define HTTP_SEND_RESPONSE_FLAG_OPAQUE              0x00000040
#define HTTP_SEND_RESPONSE_FLAG_GOAWAY              0x00000100
#define HTTP_SEND_RESPONSE_FLAG_AUTOMATIC_CHUNKING  0x00000200


//
// Flags for HttpFlushResponseCache().
//
// HTTP_FLUSH_RESPONSE_FLAG_RECURSIVE - Flushes the specified URL and all
// hierarchally-related sub-URLs from the response or fragment cache.
//

#define HTTP_FLUSH_RESPONSE_FLAG_RECURSIVE          0x00000001


//
// Opaque identifiers for various HTTPAPI objects.
//

typedef ULONGLONG      HTTP_OPAQUE_ID,         *PHTTP_OPAQUE_ID;

typedef HTTP_OPAQUE_ID HTTP_REQUEST_ID,        *PHTTP_REQUEST_ID;
typedef HTTP_OPAQUE_ID HTTP_CONNECTION_ID,     *PHTTP_CONNECTION_ID;
typedef HTTP_OPAQUE_ID HTTP_RAW_CONNECTION_ID, *PHTTP_RAW_CONNECTION_ID;

#if _WIN32_WINNT >= 0x0600

typedef HTTP_OPAQUE_ID HTTP_URL_GROUP_ID,      *PHTTP_URL_GROUP_ID;
typedef HTTP_OPAQUE_ID HTTP_SERVER_SESSION_ID, *PHTTP_SERVER_SESSION_ID;

// #if _WIN32_WINNT >= Somevalue
typedef HTTP_OPAQUE_ID HTTP_CLIENT_REQUEST_ID, *PHTTP_CLIENT_REQUEST_ID;
typedef HTTP_OPAQUE_ID HTTP_CLIENT_CONNECTION_ID, *PHTTP_CLIENT_CONNECTION_ID;
typedef HTTP_OPAQUE_ID HTTP_CLIENT_STREAM_ID, *PHTTP_CLIENT_STREAM_ID;
typedef HTTP_OPAQUE_ID HTTP_CLIENT_CREDENTIAL_ID, *PHTTP_CLIENT_CREDENTIAL_ID;

#endif // _WIN32_WINNT >= 0x0600

//
// Macros for opaque identifier manipulations.
//

#define HTTP_NULL_ID            (0ui64)
#define HTTP_IS_NULL_ID(pid)    (HTTP_NULL_ID == *(pid))
#define HTTP_SET_NULL_ID(pid)   (*(pid) = HTTP_NULL_ID)

//
// This structure defines a file byte range.
//
// If the Length field is HTTP_BYTE_RANGE_TO_EOF then the remainder of the
// file (everything after StartingOffset) is sent.
//

#define HTTP_BYTE_RANGE_TO_EOF ((ULONGLONG)-1)

typedef struct _HTTP_BYTE_RANGE
{
    ULARGE_INTEGER StartingOffset;
    ULARGE_INTEGER Length;

} HTTP_BYTE_RANGE, *PHTTP_BYTE_RANGE;

//
// The type for HTTP protocol version numbers.
//

#ifdef HTTP_VERSION
#undef HTTP_VERSION
#endif

typedef struct _HTTP_VERSION
{
    USHORT MajorVersion;
    USHORT MinorVersion;

} HTTP_VERSION, *PHTTP_VERSION;

//
// Some useful macros for HTTP protocol version manipulation.
//

#define HTTP_VERSION_UNKNOWN    { 0, 0 }
#define HTTP_VERSION_0_9        { 0, 9 }
#define HTTP_VERSION_1_0        { 1, 0 }
#define HTTP_VERSION_1_1        { 1, 1 }
#define HTTP_VERSION_2_0        { 2, 0 }
#define HTTP_VERSION_3_0        { 3, 0 }

#define HTTP_SET_VERSION(version, major, minor)             \
do {                                                        \
    (version).MajorVersion = (major);                       \
    (version).MinorVersion = (minor);                       \
} while (0)

#define HTTP_EQUAL_VERSION(version, major, minor)           \
    ((version).MajorVersion == (major) &&                   \
     (version).MinorVersion == (minor))

#define HTTP_GREATER_VERSION(version, major, minor)         \
    ((version).MajorVersion > (major) ||                    \
     ((version).MajorVersion == (major) &&                  \
      (version).MinorVersion > (minor)))

#define HTTP_LESS_VERSION(version, major, minor)            \
    ((version).MajorVersion < (major) ||                    \
     ((version).MajorVersion == (major) &&                  \
      (version).MinorVersion < (minor)))

#define HTTP_NOT_EQUAL_VERSION(version, major, minor)       \
    (!HTTP_EQUAL_VERSION(version, major, minor))

#define HTTP_GREATER_EQUAL_VERSION(version, major, minor)   \
    (!HTTP_LESS_VERSION(version, major, minor))

#define HTTP_LESS_EQUAL_VERSION(version, major, minor)      \
    (!HTTP_GREATER_VERSION(version, major, minor))

//
// The enum type for HTTP Scheme.
//

typedef enum _HTTP_URI_SCHEME
{
    HttpSchemeHttp,
    HttpSchemeHttps,
    HttpSchemeMaximum
} HTTP_SCHEME, *PHTTP_URI_SCHEME;

//
// The enum type for HTTP verbs.
//

typedef enum _HTTP_VERB
{
    HttpVerbUnparsed,
    HttpVerbUnknown,
    HttpVerbInvalid,
    HttpVerbOPTIONS,
    HttpVerbGET,
    HttpVerbHEAD,
    HttpVerbPOST,
    HttpVerbPUT,
    HttpVerbDELETE,
    HttpVerbTRACE,
    HttpVerbCONNECT,
    HttpVerbTRACK,  // used by Microsoft Cluster Server for a non-logged trace
    HttpVerbMOVE,
    HttpVerbCOPY,
    HttpVerbPROPFIND,
    HttpVerbPROPPATCH,
    HttpVerbMKCOL,
    HttpVerbLOCK,
    HttpVerbUNLOCK,
    HttpVerbSEARCH,

    HttpVerbMaximum

} HTTP_VERB, *PHTTP_VERB;

//
// Symbols for all HTTP/1.1 headers and other tokens. Notice request +
// response values overlap. Make sure you know which type of header array
// you are indexing.
//
// These values are used as offsets into arrays and as token values in
// HTTP_KNOWN_HEADER arrays in HTTP_REQUEST_HEADERS and HTTP_RESPONSE_HEADERS.
//
// See RFC 2616, HTTP/1.1, for further explanation of most of these headers.
//

typedef enum _HTTP_HEADER_ID
{
    HttpHeaderCacheControl          = 0,    // general-header [section 4.5]
    HttpHeaderConnection            = 1,    // general-header [section 4.5]
    HttpHeaderDate                  = 2,    // general-header [section 4.5]
    HttpHeaderKeepAlive             = 3,    // general-header [not in rfc]
    HttpHeaderPragma                = 4,    // general-header [section 4.5]
    HttpHeaderTrailer               = 5,    // general-header [section 4.5]
    HttpHeaderTransferEncoding      = 6,    // general-header [section 4.5]
    HttpHeaderUpgrade               = 7,    // general-header [section 4.5]
    HttpHeaderVia                   = 8,    // general-header [section 4.5]
    HttpHeaderWarning               = 9,    // general-header [section 4.5]

    HttpHeaderAllow                 = 10,   // entity-header  [section 7.1]
    HttpHeaderContentLength         = 11,   // entity-header  [section 7.1]
    HttpHeaderContentType           = 12,   // entity-header  [section 7.1]
    HttpHeaderContentEncoding       = 13,   // entity-header  [section 7.1]
    HttpHeaderContentLanguage       = 14,   // entity-header  [section 7.1]
    HttpHeaderContentLocation       = 15,   // entity-header  [section 7.1]
    HttpHeaderContentMd5            = 16,   // entity-header  [section 7.1]
    HttpHeaderContentRange          = 17,   // entity-header  [section 7.1]
    HttpHeaderExpires               = 18,   // entity-header  [section 7.1]
    HttpHeaderLastModified          = 19,   // entity-header  [section 7.1]

    // Request Headers

    HttpHeaderAccept                = 20,   // request-header [section 5.3]
    HttpHeaderAcceptCharset         = 21,   // request-header [section 5.3]
    HttpHeaderAcceptEncoding        = 22,   // request-header [section 5.3]
    HttpHeaderAcceptLanguage        = 23,   // request-header [section 5.3]
    HttpHeaderAuthorization         = 24,   // request-header [section 5.3]
    HttpHeaderCookie                = 25,   // request-header [not in rfc]
    HttpHeaderExpect                = 26,   // request-header [section 5.3]
    HttpHeaderFrom                  = 27,   // request-header [section 5.3]
    HttpHeaderHost                  = 28,   // request-header [section 5.3]
    HttpHeaderIfMatch               = 29,   // request-header [section 5.3]

    HttpHeaderIfModifiedSince       = 30,   // request-header [section 5.3]
    HttpHeaderIfNoneMatch           = 31,   // request-header [section 5.3]
    HttpHeaderIfRange               = 32,   // request-header [section 5.3]
    HttpHeaderIfUnmodifiedSince     = 33,   // request-header [section 5.3]
    HttpHeaderMaxForwards           = 34,   // request-header [section 5.3]
    HttpHeaderProxyAuthorization    = 35,   // request-header [section 5.3]
    HttpHeaderReferer               = 36,   // request-header [section 5.3]
    HttpHeaderRange                 = 37,   // request-header [section 5.3]
    HttpHeaderTe                    = 38,   // request-header [section 5.3]
    HttpHeaderTranslate             = 39,   // request-header [webDAV, not in rfc 2518]

    HttpHeaderUserAgent             = 40,   // request-header [section 5.3]

    HttpHeaderRequestMaximum        = 41,

    // Response Headers

    HttpHeaderAcceptRanges          = 20,   // response-header [section 6.2]
    HttpHeaderAge                   = 21,   // response-header [section 6.2]
    HttpHeaderEtag                  = 22,   // response-header [section 6.2]
    HttpHeaderLocation              = 23,   // response-header [section 6.2]
    HttpHeaderProxyAuthenticate     = 24,   // response-header [section 6.2]
    HttpHeaderRetryAfter            = 25,   // response-header [section 6.2]
    HttpHeaderServer                = 26,   // response-header [section 6.2]
    HttpHeaderSetCookie             = 27,   // response-header [not in rfc]
    HttpHeaderVary                  = 28,   // response-header [section 6.2]
    HttpHeaderWwwAuthenticate       = 29,   // response-header [section 6.2]

    HttpHeaderResponseMaximum       = 30,

    HttpHeaderMaximum               = 41

} HTTP_HEADER_ID, *PHTTP_HEADER_ID;


//
// Structure defining format of a known HTTP header.
// Name is from HTTP_HEADER_ID.
//

typedef struct _HTTP_KNOWN_HEADER
{
    USHORT RawValueLength;     // in bytes not including the NUL
    PCSTR  pRawValue;

} HTTP_KNOWN_HEADER, *PHTTP_KNOWN_HEADER;

//
// Structure defining format of an unknown header.
//

typedef struct _HTTP_UNKNOWN_HEADER
{
    USHORT NameLength;          // in bytes not including the NUL
    USHORT RawValueLength;      // in bytes not including the NUL
    PCSTR  pName;               // The header name (minus the ':' character)
    PCSTR  pRawValue;           // The header value

} HTTP_UNKNOWN_HEADER, *PHTTP_UNKNOWN_HEADER;

#if _WIN32_WINNT >= 0x0600

//
// Log fields data structure is used for logging a request. This structure must
// be provided along with an HttpSendHttpResponse or HttpSendResponseEntityBody
// call that concludes the send.
//

// Base structure is for future versioning.

typedef enum _HTTP_LOG_DATA_TYPE
{
    HttpLogDataTypeFields = 0

} HTTP_LOG_DATA_TYPE, *PHTTP_LOG_DATA_TYPE;

// should we DECLSPEC_ALIGN(4 or 8) == DECLSPEC_POINTERALIGN?
typedef struct _HTTP_LOG_DATA
{
    HTTP_LOG_DATA_TYPE Type;

} HTTP_LOG_DATA, *PHTTP_LOG_DATA;

// Current log fields data structure for of type HttpLogDataTypeFields.

typedef struct _HTTP_LOG_FIELDS_DATA
{
    HTTP_LOG_DATA Base;

    USHORT UserNameLength;
    USHORT UriStemLength;
    USHORT ClientIpLength;
    USHORT ServerNameLength;
    USHORT ServiceNameLength;
    USHORT ServerIpLength;
    USHORT MethodLength;
    USHORT UriQueryLength;
    USHORT HostLength;
    USHORT UserAgentLength;
    USHORT CookieLength;
    USHORT ReferrerLength;

    PWCHAR UserName;
    PWCHAR UriStem;
    PCHAR  ClientIp;
    PCHAR  ServerName;
    PCHAR  ServiceName;
    PCHAR  ServerIp;
    PCHAR  Method;
    PCHAR  UriQuery;
    PCHAR  Host;
    PCHAR  UserAgent;
    PCHAR  Cookie;
    PCHAR  Referrer;

    USHORT ServerPort;
    USHORT ProtocolStatus;

    ULONG  Win32Status;

    HTTP_VERB MethodNum;

    USHORT SubStatus;

} HTTP_LOG_FIELDS_DATA, *PHTTP_LOG_FIELDS_DATA;

#endif // _WIN32_WINNT >= 0x0600


typedef struct _HTTP_WINHTTP_FAST_FORWARDING_DATA
{
    UCHAR Reserved[16];
} HTTP_WINHTTP_FAST_FORWARDING_DATA, *PHTTP_WINHTTP_FAST_FORWARDING_DATA;


//
// This enum defines a data source for a particular chunk of data.
//

typedef enum _HTTP_DATA_CHUNK_TYPE
{
    HttpDataChunkFromMemory,
    HttpDataChunkFromFileHandle,
    HttpDataChunkFromFragmentCache,
    HttpDataChunkFromFragmentCacheEx,
    HttpDataChunkTrailers,
    HttpDataChunkFromWinHttpFastForwarding,

    HttpDataChunkMaximum

} HTTP_DATA_CHUNK_TYPE, *PHTTP_DATA_CHUNK_TYPE;

//
// This structure describes an individual data chunk.
//

typedef struct _HTTP_DATA_CHUNK
{
    //
    // The type of this data chunk.
    //

    HTTP_DATA_CHUNK_TYPE DataChunkType;

    //
    // The data chunk structures, one per supported data chunk type.
    //

    union
    {
        //
        // From-memory data chunk.
        //

        struct
        {
            PVOID pBuffer;
            ULONG BufferLength;

        } FromMemory;

        //
        // From-file handle data chunk.
        //

        struct
        {
            HTTP_BYTE_RANGE ByteRange;
            HANDLE          FileHandle;

        } FromFileHandle;

        //
        // From-fragment cache data chunk.
        //

        struct
        {
            USHORT FragmentNameLength;      // in bytes not including the NUL
            PCWSTR pFragmentName;

        } FromFragmentCache;

        //
        // From-fragment cache data chunk that specifies a byte range.
        //

        struct
        {
            HTTP_BYTE_RANGE ByteRange;
            PCWSTR pFragmentName;           // NULL-terminated string

        } FromFragmentCacheEx;

        //
        // Trailer data chunk that specifies Trailer headers.
        //

        struct
        {
            USHORT TrailerCount;
            PHTTP_UNKNOWN_HEADER pTrailers;

        } Trailers;

        struct
        {
            HTTP_WINHTTP_FAST_FORWARDING_DATA WhFastForwardingData;
        } FromWinHttpFastForwarding;
    };

} HTTP_DATA_CHUNK, *PHTTP_DATA_CHUNK;

//
// HTTP API doesn't support 16 bit applications.
// Neither WIN32 nor _WIN64 was defined.
//

C_ASSERT(TYPE_ALIGNMENT(HTTP_DATA_CHUNK) == sizeof(ULONGLONG));

//
// Structure defining format of request headers.
//

typedef struct _HTTP_REQUEST_HEADERS
{
    //
    // The array of unknown HTTP headers and the number of
    // entries in the array.
    //

    USHORT               UnknownHeaderCount;
    PHTTP_UNKNOWN_HEADER pUnknownHeaders;

    //
    // Trailers - we don't use these currently, reserved for a future release
    //
    USHORT               TrailerCount;   // Reserved, must be 0
    PHTTP_UNKNOWN_HEADER pTrailers;      // Reserved, must be NULL


    //
    // Known headers.
    //

    HTTP_KNOWN_HEADER    KnownHeaders[HttpHeaderRequestMaximum];

} HTTP_REQUEST_HEADERS, *PHTTP_REQUEST_HEADERS;

//
// Structure defining format of response headers.
//

typedef struct _HTTP_RESPONSE_HEADERS
{
    //
    // The array of unknown HTTP headers and the number of
    // entries in the array.
    //

    USHORT               UnknownHeaderCount;
    PHTTP_UNKNOWN_HEADER pUnknownHeaders;

    //
    // Trailers - we don't use these currently, reserved for a future release
    //
    USHORT               TrailerCount;   // Reserved, must be 0
    PHTTP_UNKNOWN_HEADER pTrailers;      // Reserved, must be NULL

    //
    // Known headers.
    //

    HTTP_KNOWN_HEADER    KnownHeaders[HttpHeaderResponseMaximum];

} HTTP_RESPONSE_HEADERS, *PHTTP_RESPONSE_HEADERS;

//
// Properties that can be passed down with IOCTL_HTTP_DELEGATE_REQUEST_EX
//

typedef enum _HTTP_DELEGATE_REQUEST_PROPERTY_ID
{
    DelegateRequestReservedProperty,
    DelegateRequestDelegateUrlProperty,
} HTTP_DELEGATE_REQUEST_PROPERTY_ID, *PHTTP_DELEGATE_REQUEST_PROPERTY_ID;

typedef struct _HTTP_DELEGATE_REQUEST_PROPERTY_INFO
{
    HTTP_DELEGATE_REQUEST_PROPERTY_ID PropertyId;
    ULONG PropertyInfoLength;
    PVOID PropertyInfo;
} HTTP_DELEGATE_REQUEST_PROPERTY_INFO, *PHTTP_DELEGATE_REQUEST_PROPERTY_INFO;

//
// Properties that can be passed down with IOCTL_HTTP_CREATE_REQUEST_QUEUE_EX
//

typedef enum _HTTP_CREATE_REQUEST_QUEUE_PROPERTY_ID
{
    CreateRequestQueueExternalIdProperty = 1,
    CreateRequestQueueMax
} HTTP_CREATE_REQUEST_QUEUE_PROPERTY_ID, *PHTTP_CREATE_REQUEST_QUEUE_PROPERTY_ID;

typedef struct _HTTP_CREATE_REQUEST_QUEUE_PROPERTY_INFO
{
    HTTP_CREATE_REQUEST_QUEUE_PROPERTY_ID PropertyId;
    ULONG PropertyInfoLength;
    PVOID PropertyInfo;
} HTTP_CREATE_REQUEST_QUEUE_PROPERTY_INFO, *PHTTP_CREATE_REQUEST_QUEUE_PROPERTY_INFO;

//
// Structure defining format of transport address. Use pLocalAddress->sa_family
// to determine whether this is an IPv4 address (AF_INET) or IPv6 (AF_INET6).
//
// pRemoteAddress->sa_family will be the same as pLocalAddress->sa_family.
//
// SOCKADDRs are always in network order, not host order.
//

typedef struct _HTTP_TRANSPORT_ADDRESS
{
    PSOCKADDR      pRemoteAddress;
    PSOCKADDR      pLocalAddress;

} HTTP_TRANSPORT_ADDRESS, *PHTTP_TRANSPORT_ADDRESS;

//
// Structure defining format of cooked URL.
//

typedef struct _HTTP_COOKED_URL
{
    //
    // Pointers overlap and point into pFullUrl. NULL if not present.
    //

    USHORT FullUrlLength;       // in bytes not including the NUL
    USHORT HostLength;          // in bytes (no NUL)
    USHORT AbsPathLength;       // in bytes (no NUL)
    USHORT QueryStringLength;   // in bytes (no NUL)

    PCWSTR pFullUrl;     // points to "http://hostname:port/abs/.../path?query"
    PCWSTR pHost;        // points to the first char in the hostname
    PCWSTR pAbsPath;     // Points to the 3rd '/' char
    PCWSTR pQueryString; // Points to the 1st '?' char or NULL

} HTTP_COOKED_URL, *PHTTP_COOKED_URL;

//
// An opaque context for URL manipulation.
//

typedef ULONGLONG HTTP_URL_CONTEXT;


#if _WIN32_WINNT >= 0x0600

//
// Optional flags for URL manipulation functions.
//
// HTTP_URL_FLAG_REMOVE_ALL : When this flag is used
// when removing a Url from a url group, regardless of
// the passed URL, all of the Urls from the url group
// will be removed.
//

#define HTTP_URL_FLAG_REMOVE_ALL                0x00000001


//
// Request Authentication related.
//

typedef enum _HTTP_AUTH_STATUS
{
    HttpAuthStatusSuccess,
    HttpAuthStatusNotAuthenticated,
    HttpAuthStatusFailure

} HTTP_AUTH_STATUS, *PHTTP_AUTH_STATUS;


typedef enum _HTTP_REQUEST_AUTH_TYPE
{
    HttpRequestAuthTypeNone = 0,
    HttpRequestAuthTypeBasic,
    HttpRequestAuthTypeDigest,
    HttpRequestAuthTypeNTLM,
    HttpRequestAuthTypeNegotiate,
    HttpRequestAuthTypeKerberos


} HTTP_REQUEST_AUTH_TYPE, *PHTTP_REQUEST_AUTH_TYPE;

#endif // _WIN32_WINNT >= 0x0600

//
// SSL Client certificate information.
//

typedef struct _HTTP_SSL_CLIENT_CERT_INFO
{
    ULONG   CertFlags;
    ULONG   CertEncodedSize;
    PUCHAR  pCertEncoded;
    HANDLE  Token;
    BOOLEAN CertDeniedByMapper;

} HTTP_SSL_CLIENT_CERT_INFO, *PHTTP_SSL_CLIENT_CERT_INFO;

#if _WIN32_WINNT >= _WIN32_WINNT_WIN7

//
// Flag to retrieve secure channel binding with HttpReceiveClientCertificate
//

#define HTTP_RECEIVE_SECURE_CHANNEL_TOKEN 0x1

//
// Flag to retrieve full certificate chain with HttpReceiveClientCertificate
//

#define HTTP_RECEIVE_FULL_CHAIN 0x2

#endif

//
// Data computed during SSL handshake.
//

typedef struct _HTTP_SSL_INFO
{
    USHORT ServerCertKeySize;
    USHORT ConnectionKeySize;
    ULONG  ServerCertIssuerSize;
    ULONG  ServerCertSubjectSize;

    PCSTR  pServerCertIssuer;
    PCSTR  pServerCertSubject;

    PHTTP_SSL_CLIENT_CERT_INFO pClientCertInfo;
    ULONG                      SslClientCertNegotiated;

} HTTP_SSL_INFO, *PHTTP_SSL_INFO;

//
// HttpRequestInfoTypeSslProtocol payload.  Contains basic information about the
// SSL/TLS protocol and cipher.  See SecPkgContext_ConnectionInfo documentation
// for details.  This information is meant for statistics.  Do not use this for
// security enforcement because by the time you check this the client may
// already have transmitted the information being protected (e.g. HTTP request
// headers).
//

typedef struct _HTTP_SSL_PROTOCOL_INFO
{
    ULONG Protocol;
    ULONG CipherType;
    ULONG CipherStrength;
    ULONG HashType;
    ULONG HashStrength;
    ULONG KeyExchangeType;
    ULONG KeyExchangeStrength;

} HTTP_SSL_PROTOCOL_INFO, *PHTTP_SSL_PROTOCOL_INFO;

//
// List of possible sizes for which information will be retured in HTTP_REQUEST_SIZING_INFO.
//

typedef enum  _HTTP_REQUEST_SIZING_TYPE
{
    HttpRequestSizingTypeTlsHandshakeLeg1ClientData, // Inbound/outbound data?
    HttpRequestSizingTypeTlsHandshakeLeg1ServerData,
    HttpRequestSizingTypeTlsHandshakeLeg2ClientData,
    HttpRequestSizingTypeTlsHandshakeLeg2ServerData,
    HttpRequestSizingTypeHeaders,
    HttpRequestSizingTypeMax

} HTTP_REQUEST_SIZING_TYPE, *PHTTP_REQUEST_SIZING_TYPE;

//
// Flag values for HTTP_REQUEST_SIZING_INFO
//

#define HTTP_REQUEST_SIZING_INFO_FLAG_TCP_FAST_OPEN          0x00000001
#define HTTP_REQUEST_SIZING_INFO_FLAG_TLS_SESSION_RESUMPTION 0x00000002
#define HTTP_REQUEST_SIZING_INFO_FLAG_TLS_FALSE_START        0x00000004
#define HTTP_REQUEST_SIZING_INFO_FLAG_FIRST_REQUEST          0x00000008

//
// HttpRequestInfoTypeSizeInfo payload. Contains size information filled by
// each processsing stage.
//

typedef struct _HTTP_REQUEST_SIZING_INFO
{
    ULONGLONG Flags;
    ULONG RequestIndex;
    ULONG RequestSizingCount;
    ULONGLONG RequestSizing[HttpRequestSizingTypeMax];

} HTTP_REQUEST_SIZING_INFO, *PHTTP_REQUEST_SIZING_INFO;

//
// List of possible request timings for which information will be retured in
// HTTP_REQUEST_TIMING_INFO. Not all timings apply for every request.
//

typedef enum _HTTP_REQUEST_TIMING_TYPE
{
    HttpRequestTimingTypeConnectionStart,
    HttpRequestTimingTypeDataStart,
    HttpRequestTimingTypeTlsCertificateLoadStart,
    HttpRequestTimingTypeTlsCertificateLoadEnd,
    HttpRequestTimingTypeTlsHandshakeLeg1Start,
    HttpRequestTimingTypeTlsHandshakeLeg1End,
    HttpRequestTimingTypeTlsHandshakeLeg2Start,
    HttpRequestTimingTypeTlsHandshakeLeg2End,
    HttpRequestTimingTypeTlsAttributesQueryStart,
    HttpRequestTimingTypeTlsAttributesQueryEnd,
    HttpRequestTimingTypeTlsClientCertQueryStart,
    HttpRequestTimingTypeTlsClientCertQueryEnd,
    HttpRequestTimingTypeHttp2StreamStart,
    HttpRequestTimingTypeHttp2HeaderDecodeStart,
    HttpRequestTimingTypeHttp2HeaderDecodeEnd,
    HttpRequestTimingTypeRequestHeaderParseStart,
    HttpRequestTimingTypeRequestHeaderParseEnd,
    HttpRequestTimingTypeRequestRoutingStart,
    HttpRequestTimingTypeRequestRoutingEnd,
    HttpRequestTimingTypeRequestQueuedForInspection,
    HttpRequestTimingTypeRequestDeliveredForInspection,
    HttpRequestTimingTypeRequestReturnedAfterInspection,
    HttpRequestTimingTypeRequestQueuedForDelegation,
    HttpRequestTimingTypeRequestDeliveredForDelegation,
    HttpRequestTimingTypeRequestReturnedAfterDelegation,
    HttpRequestTimingTypeRequestQueuedForIO,
    HttpRequestTimingTypeRequestDeliveredForIO,
    HttpRequestTimingTypeHttp3StreamStart,
    HttpRequestTimingTypeHttp3HeaderDecodeStart,
    HttpRequestTimingTypeHttp3HeaderDecodeEnd,
    HttpRequestTimingTypeMax

} HTTP_REQUEST_TIMING_TYPE, *PHTTP_REQUEST_TIMING_TYPE;

//
// HttpRequestInfoTypeTiming payload.  Contains information about how much
// time was spent at each request processing stage.
//

typedef struct _HTTP_REQUEST_TIMING_INFO
{
    ULONG RequestTimingCount;
    ULONGLONG RequestTiming[HttpRequestTimingTypeMax];

} HTTP_REQUEST_TIMING_INFO, *PHTTP_REQUEST_TIMING_INFO;

typedef struct _HTTP_REQUEST_TRANSPORT_IDLE_CONNECTION_TIMEOUT_INFO
{
    USHORT TransportIdleConnectionTimeout;

} HTTP_REQUEST_TRANSPORT_IDLE_CONNECTION_TIMEOUT_INFO, *PHTTP_REQUEST_TRANSPORT_IDLE_CONNECTION_TIMEOUT_INFO;

typedef struct _HTTP_REQUEST_DSCP_INFO
{
    BYTE DscpTag;

} HTTP_REQUEST_DSCP_INFO, *PHTTP_REQUEST_DSCP_INFO;

typedef struct _HTTP_REQUEST_INITIAL_PACKET_TTL_INFO
{
    BYTE InitialPacketTtl;
} HTTP_REQUEST_INITIAL_PACKET_TTL_INFO, *PHTTP_REQUEST_INITIAL_PACKET_TTL_INFO;

#if _WIN32_WINNT >= 0x0600

//
// Generic request information type.
//

typedef enum _HTTP_REQUEST_INFO_TYPE
{
    HttpRequestInfoTypeAuth,
    HttpRequestInfoTypeChannelBind,
    HttpRequestInfoTypeSslProtocol,
    HttpRequestInfoTypeSslTokenBindingDraft,
    HttpRequestInfoTypeSslTokenBinding,
    HttpRequestInfoTypeRequestTiming,
    HttpRequestInfoTypeTcpInfoV0,
    HttpRequestInfoTypeRequestSizing,
    HttpRequestInfoTypeQuicStats,
    HttpRequestInfoTypeTcpInfoV1,
    HttpRequestInfoTypeQuicStatsV2,
    HttpRequestInfoTypeTcpInfoV2,
    HttpRequestInfoTypeTransportIdleConnectionTimeout,
    HttpRequestInfoTypeDscpTag,
    HttpRequestInfoTypeInitialPacketTtl,

} HTTP_REQUEST_INFO_TYPE, *PHTTP_REQUEST_INFO_TYPE;

typedef struct _HTTP_REQUEST_INFO
{
    HTTP_REQUEST_INFO_TYPE InfoType;
    ULONG                  InfoLength;
    PVOID                  pInfo;

} HTTP_REQUEST_INFO, *PHTTP_REQUEST_INFO;

#ifndef __SECSTATUS_DEFINED__
typedef LONG SECURITY_STATUS;
#define __SECSTATUS_DEFINED__
#endif // __SECSTATUS_DEFINED__

//
// Authentication request info structure
//

#define HTTP_REQUEST_AUTH_FLAG_TOKEN_FOR_CACHED_CRED (0x00000001)

typedef struct _HTTP_REQUEST_AUTH_INFO
{
    HTTP_AUTH_STATUS AuthStatus;
    SECURITY_STATUS  SecStatus;

    ULONG Flags;

    HTTP_REQUEST_AUTH_TYPE AuthType;

    HANDLE AccessToken;
    ULONG ContextAttributes;

    //
    // Optional serialized context.
    //

    ULONG PackedContextLength;
    ULONG PackedContextType;
    PVOID PackedContext;

    //
    // Optional mutual authentication data and its length in bytes.
    //

    ULONG MutualAuthDataLength;
    PCHAR pMutualAuthData;

    //
    // For SSPI based schemes the package name is returned. Length does
    // not include the terminating null and it is in bytes.
    //

    USHORT PackageNameLength;
    PWSTR pPackageName;

} HTTP_REQUEST_AUTH_INFO, *PHTTP_REQUEST_AUTH_INFO;

#endif // _WIN32_WINNT >= 0x0600

//
// The structure of an HTTP request for downlevel OS
//

typedef struct _HTTP_REQUEST_V1
{
    //
    // Request flags (see HTTP_REQUEST_FLAG_* definitions below).
    //

    ULONG Flags;

    //
    // An opaque request identifier. These values are used by the driver
    // to correlate outgoing responses with incoming requests.
    //

    HTTP_CONNECTION_ID ConnectionId;
    HTTP_REQUEST_ID    RequestId;

    //
    // The context associated with the URL prefix.
    //

    HTTP_URL_CONTEXT UrlContext;

    //
    // The HTTP version number.
    //

    HTTP_VERSION Version;

    //
    // The request verb.
    //

    HTTP_VERB Verb;

    //
    // The length of the verb string if the Verb field is HttpVerbUnknown.
    //

    USHORT UnknownVerbLength;           // in bytes not including the NUL

    //
    // The length of the raw (uncooked) URL
    //

    USHORT RawUrlLength;                // in bytes not including the NUL

    //
    // Pointer to the verb string if the Verb field is HttpVerbUnknown.
    //

    PCSTR  pUnknownVerb;

    //
    // Pointer to the raw (uncooked) URL
    //

    PCSTR  pRawUrl;

    //
    // The canonicalized Unicode URL
    //

    HTTP_COOKED_URL CookedUrl;

    //
    // Local and remote transport addresses for the connection.
    //

    HTTP_TRANSPORT_ADDRESS Address;

    //
    // The request headers.
    //

    HTTP_REQUEST_HEADERS Headers;

    //
    // The total number of bytes received from network for this request.
    //

    ULONGLONG BytesReceived;

    //
    // pEntityChunks is an array of EntityChunkCount HTTP_DATA_CHUNKs. The
    // entity body is copied only if HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY
    // was passed to HttpReceiveHttpRequest().
    //

    USHORT           EntityChunkCount;
    PHTTP_DATA_CHUNK pEntityChunks;

    //
    // SSL connection information.
    //

    HTTP_RAW_CONNECTION_ID RawConnectionId;
    PHTTP_SSL_INFO         pSslInfo;

} HTTP_REQUEST_V1, *PHTTP_REQUEST_V1;

#if _WIN32_WINNT >= 0x0600

// Vista

//
// Version 2.0 members are defined here
// N.B. One must define V2 elements in two places :(
//      This is due to the fact that C++ doesn't allow anonymous
//      structure declarations and one must use structure
//      inheritance instead.
//

#ifdef __cplusplus

typedef struct _HTTP_REQUEST_V2 : _HTTP_REQUEST_V1
{
    //
    // Version 1.0 members are inherited
    // Version 2.0 members are declared below
    //

    //
    // Additional Request Informations.
    //

    USHORT             RequestInfoCount;
    PHTTP_REQUEST_INFO pRequestInfo;
} HTTP_REQUEST_V2, *PHTTP_REQUEST_V2;

#else // __cplusplus

typedef struct _HTTP_REQUEST_V2
{
    struct _HTTP_REQUEST_V1;        // Anonymous structure

    //
    // Version 2.0 members are declared below
    //

    //
    // Additional Request Informations.
    //

    USHORT             RequestInfoCount;
    PHTTP_REQUEST_INFO pRequestInfo;
} HTTP_REQUEST_V2, *PHTTP_REQUEST_V2;

#endif  // __cplusplus

typedef HTTP_REQUEST_V2 HTTP_REQUEST;

#else // _WIN32_WINNT >= 0x0600

typedef HTTP_REQUEST_V1 HTTP_REQUEST;

#endif  // _WIN32_WINNT >= 0x0600

typedef HTTP_REQUEST * PHTTP_REQUEST;


//
// Values for HTTP_REQUEST::Flags. Zero or more of these may be ORed together.
//
// HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS - there is more entity body
// to be read for this request. Otherwise, there is no entity body or
// all of the entity body was copied into pEntityChunks.
// HTTP_REQUEST_FLAG_IP_ROUTED - This flag indicates that the request has been
// routed based on host plus ip or ip binding.This is a hint for the application
// to include the local ip while flushing kernel cache entries build for this
// request if any.
// HTTP_REQUEST_FLAG_HTTP2 - Indicates the request was received over HTTP/2.
// HTTP_REQUEST_FLAG_HTTP3 - Indicates the request was received over HTTP/3.
// HTTP_REQUEST_FLAG_FAST_FORWARDING_RESPONSE_ALLOWED - Indicates the response
//                                                      is eligible for
//                                                      fast-forwarding.
// HTTP_REQUEST_FLAG_FAST_FORWARDING_ALLOWED - This should not be used, it is
//                                             the old flag.
//                                             It has been used first, but the flag
//                                             was split into request and response
//                                             side. This old flag has the same
//                                             value as the response-side flag.
//

#define HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS            0x00000001
#define HTTP_REQUEST_FLAG_IP_ROUTED                          0x00000002
#define HTTP_REQUEST_FLAG_HTTP2                              0x00000004
#define HTTP_REQUEST_FLAG_HTTP3                              0x00000008
#define HTTP_REQUEST_FLAG_FAST_FORWARDING_ALLOWED            0x00000010
#define HTTP_REQUEST_FLAG_FAST_FORWARDING_RESPONSE_ALLOWED   HTTP_REQUEST_FLAG_FAST_FORWARDING_ALLOWED


//
// This structure describes an HTTP response.
//

typedef struct _HTTP_RESPONSE_V1
{
    //
    // Response flags (see HTTP_RESPONSE_FLAG_* definitions below).
    //

    ULONG Flags;

    //
    // The raw HTTP protocol version number.
    //

    HTTP_VERSION Version;

    //
    // The HTTP status code (e.g., 200).
    //

    USHORT StatusCode;

    //
    // The HTTP reason (e.g., "OK"). This MUST not contain
    // non-ASCII characters (i.e., all chars must be in range 0x20-0x7E).
    //

    USHORT ReasonLength;                 // in bytes not including the '\0'
    PCSTR  pReason;

    //
    // The response headers.
    //

    HTTP_RESPONSE_HEADERS Headers;

    //
    // pEntityChunks points to an array of EntityChunkCount HTTP_DATA_CHUNKs.
    //

    USHORT           EntityChunkCount;
    PHTTP_DATA_CHUNK pEntityChunks;

} HTTP_RESPONSE_V1, *PHTTP_RESPONSE_V1;

#if _WIN32_WINNT >= 0x0600

//
// Values for HTTP_RESPONSE::Flags.
//
// HTTP_RESPONSE_FLAG_MULTIPLE_ENCODINGS_AVAILABLE - Set this flag if encodings
// other than identity form are available for this resource.This flag is ignored
// if application has not asked for response to be cached. It's used as a hint
// to the Http Server API for content negotiation  used when serving from the
// the kernel response cache.
//
// HTTP_RESPONSE_FLAG_MORE_ENTITY_BODY_EXISTS - there is more entity body
// to be read for this response.  Otherwise, there is no entity body or
// all of the entity body was copied into pEntityChunks.
//

#define HTTP_RESPONSE_FLAG_MULTIPLE_ENCODINGS_AVAILABLE 0x00000001
#define HTTP_RESPONSE_FLAG_MORE_ENTITY_BODY_EXISTS   0x00000002


typedef enum _HTTP_RESPONSE_INFO_TYPE
{
    HttpResponseInfoTypeMultipleKnownHeaders,
    HttpResponseInfoTypeAuthenticationProperty,
    HttpResponseInfoTypeQoSProperty,
    HttpResponseInfoTypeChannelBind

} HTTP_RESPONSE_INFO_TYPE, *PHTTP_RESPONSE_INFO_TYPE;

typedef struct _HTTP_RESPONSE_INFO
{
    HTTP_RESPONSE_INFO_TYPE Type;
    ULONG                   Length;
    PVOID                   pInfo;
} HTTP_RESPONSE_INFO, *PHTTP_RESPONSE_INFO;

#define HTTP_RESPONSE_INFO_FLAGS_PRESERVE_ORDER         0x00000001

//
// This structure allows the provision of providing multiple known headers.
//

typedef struct _HTTP_MULTIPLE_KNOWN_HEADERS
{
    //
    // Known header id.
    //

    HTTP_HEADER_ID      HeaderId;

    ULONG               Flags;

    //
    // Number of headers of the same category.
    //

    USHORT              KnownHeaderCount;

    //
    // Array of known header structures.
    //

    PHTTP_KNOWN_HEADER  KnownHeaders;

} HTTP_MULTIPLE_KNOWN_HEADERS, *PHTTP_MULTIPLE_KNOWN_HEADERS;

//
// Version 2.0 members are defined here
// N.B. One must define V2 elements in two places :(
//      This is due to the fact that C++ doesn't allow anonymous
//      structure declarations and one must use structure
//      inheritance instead.
//

#ifdef __cplusplus

typedef struct _HTTP_RESPONSE_V2 : _HTTP_RESPONSE_V1
{
    //
    // Version 1.0 members are inherited
    // Version 2.0 members are declared below
    //

    USHORT ResponseInfoCount;
    PHTTP_RESPONSE_INFO pResponseInfo;

} HTTP_RESPONSE_V2, *PHTTP_RESPONSE_V2;

#else // __cplusplus

typedef struct _HTTP_RESPONSE_V2
{
    struct _HTTP_RESPONSE_V1;

    //
    // Version 2.0 members are declared below
    //

    USHORT ResponseInfoCount;
    PHTTP_RESPONSE_INFO pResponseInfo;
} HTTP_RESPONSE_V2, *PHTTP_RESPONSE_V2;

#endif  // __cplusplus

typedef HTTP_RESPONSE_V2 HTTP_RESPONSE;

#else // _WIN32_WINNT >= 0x0600

typedef HTTP_RESPONSE_V1 HTTP_RESPONSE;

#endif  // _WIN32_WINNT >= 0x0600

typedef HTTP_RESPONSE *PHTTP_RESPONSE;

//
// Api Version. This is used to ensure compatibility between applications and
// httpapi.dll and http.sys.
//
// This must not be confused with the HTTP Protocol version.
//

typedef struct _HTTPAPI_VERSION
{
    USHORT HttpApiMajorVersion;
    USHORT HttpApiMinorVersion;

} HTTPAPI_VERSION, *PHTTPAPI_VERSION;


#if _WIN32_WINNT >= 0x0600

// Vista

#define HTTPAPI_VERSION_2 { 2, 0 }

#endif // _WIN32_WINNT >= 0x0600

#define HTTPAPI_VERSION_1 { 1, 0 }

#define HTTPAPI_EQUAL_VERSION(version, major, minor)                \
    ((version).HttpApiMajorVersion == (major) &&                    \
     (version).HttpApiMinorVersion == (minor))

#define HTTPAPI_GREATER_VERSION(version, major, minor)              \
    ((version).HttpApiMajorVersion > (major) ||                     \
     ((version).HttpApiMajorVersion == (major) &&                   \
      (version).HttpApiMinorVersion > (minor)))

#define HTTPAPI_LESS_VERSION(version, major, minor)                 \
    ((version).HttpApiMajorVersion < (major) ||                     \
     ((version).HttpApiMajorVersion == (major) &&                   \
      (version).HttpApiMinorVersion < (minor)))

#define HTTPAPI_VERSION_GREATER_OR_EQUAL( version, major, minor)    \
    (!HTTPAPI_LESS_VERSION(version, major, minor))


//
// Cache control.
//

//
// This enum defines the available cache policies.
//

typedef enum _HTTP_CACHE_POLICY_TYPE
{
    HttpCachePolicyNocache,
    HttpCachePolicyUserInvalidates,
    HttpCachePolicyTimeToLive,

    HttpCachePolicyMaximum

} HTTP_CACHE_POLICY_TYPE, *PHTTP_CACHE_POLICY_TYPE;


//
//  Only cache unauthorized GETs + HEADs.
//

typedef struct _HTTP_CACHE_POLICY
{
    HTTP_CACHE_POLICY_TYPE  Policy;
    ULONG                   SecondsToLive;

} HTTP_CACHE_POLICY, *PHTTP_CACHE_POLICY;

//
// Enum that is used with HttpSetServiceConfiguration(),
// HttpQueryServiceConfiguration(), and HttpDeleteServiceConfiguration() APIs.
//

typedef enum _HTTP_SERVICE_CONFIG_ID
{
    HttpServiceConfigIPListenList,    // Set, Query & Delete.
    HttpServiceConfigSSLCertInfo,     // Set, Update, Query & Delete.
    HttpServiceConfigUrlAclInfo,      // Set, Query & Delete.
    HttpServiceConfigTimeout,         // Set, Query & Delete.
    HttpServiceConfigCache,           // Set, Query & Delete.

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8

    HttpServiceConfigSslSniCertInfo,  // Set, Update, Query & Delete.
    HttpServiceConfigSslCcsCertInfo,  // Set, Update, Query & Delete.

#endif

#if _WIN32_WINNT >= _WIN32_WINNT_WIN10

    HttpServiceConfigSetting,        // Set, Query & Delete.

#endif

    HttpServiceConfigSslCertInfoEx,
    HttpServiceConfigSslSniCertInfoEx,
    HttpServiceConfigSslCcsCertInfoEx,
    HttpServiceConfigSslScopedCcsCertInfo,
    HttpServiceConfigSslScopedCcsCertInfoEx,

    HttpServiceConfigMax

} HTTP_SERVICE_CONFIG_ID, *PHTTP_SERVICE_CONFIG_ID;

//
// Generic Query enum that can be used with HttpQueryServiceConfiguration()
//

typedef enum _HTTP_SERVICE_CONFIG_QUERY_TYPE
{
    HttpServiceConfigQueryExact,
    HttpServiceConfigQueryNext,
    HttpServiceConfigQueryMax

} HTTP_SERVICE_CONFIG_QUERY_TYPE, *PHTTP_SERVICE_CONFIG_QUERY_TYPE;

//
// These data structures are used to define the key types of the various SSL
// bindings.
//

typedef struct _HTTP_SERVICE_CONFIG_SSL_KEY
{
    PSOCKADDR pIpPort;
} HTTP_SERVICE_CONFIG_SSL_KEY, *PHTTP_SERVICE_CONFIG_SSL_KEY;

typedef struct _HTTP_SERVICE_CONFIG_SSL_KEY_EX
{
    SOCKADDR_STORAGE IpPort;
} HTTP_SERVICE_CONFIG_SSL_KEY_EX, *PHTTP_SERVICE_CONFIG_SSL_KEY_EX;


#if _WIN32_WINNT >= _WIN32_WINNT_WIN8

typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_KEY
{
    SOCKADDR_STORAGE IpPort;
    PWSTR Host;
} HTTP_SERVICE_CONFIG_SSL_SNI_KEY, *PHTTP_SERVICE_CONFIG_SSL_SNI_KEY;

typedef struct _HTTP_SERVICE_CONFIG_SSL_CCS_KEY
{
    SOCKADDR_STORAGE LocalAddress;
} HTTP_SERVICE_CONFIG_SSL_CCS_KEY, *PHTTP_SERVICE_CONFIG_SSL_CCS_KEY;

#endif

//
// Define various certificate check mode flags used by DefaultCertCheckMode.
//

#define HTTP_CERT_CHECK_MODE_NO_REVOCATION            0x00001
#define HTTP_CERT_CHECK_MODE_CACHED_REVOCATION        0x00002
#define HTTP_CERT_CHECK_MODE_USE_REVOCATION_FRESHNESS 0x00004
#define HTTP_CERT_CHECK_MODE_CACHED_URLS              0x00008
#define HTTP_CERT_CHECK_MODE_NO_AIA                   0x00010
#define HTTP_CERT_CHECK_MODE_NO_USAGE_CHECK           0x10000

//
// This defines a record for the SSL config store.
//

typedef struct _HTTP_SERVICE_CONFIG_SSL_PARAM
{
    ULONG SslHashLength;      // Length of the SSL hash (in bytes)
    PVOID pSslHash;           // Pointer to the SSL hash
    GUID  AppId;              // A unique identifier that can be used to
                              // identify the app that has set this parameter

    PWSTR pSslCertStoreName;  // Store name to read the server certificate
                              // from; defaults to "MY". Certificate must be
                              // stored in the LOCAL_MACHINE context.

    //
    // The following settings are used only for client certificates
    //

    //
    // DefaultCertCheckMode is a bit flag with the following semantics
    //  0x1     - Client certificate will not be verified for revocation
    //  0x2     - Only cached certificate revocation will be used.
    //  0x4     - Enable use of the DefaultRevocationFreshnessTime setting
    //  0x8     - Disable network URL retrieval.
    //  0x10    - Disable AIA checks.
    //  0x10000 - No usage check.

    DWORD DefaultCertCheckMode;

    //
    // DefaultRevocationFreshnessTime (seconds) - How often to check for
    // an updated Certificate revocation list (CRL). If this value is 0
    // then the new CRL is updated only if the previous one expires
    //

    DWORD DefaultRevocationFreshnessTime;

    //
    // DefaultRevocationUrlRetrievalTimeout (milliseconds) - Timeout on
    // attempt to retrieve certificate revocation list from the remote URL.
    //

    DWORD DefaultRevocationUrlRetrievalTimeout;

    //
    // pDefaultSslCtlIdentifier - Restrict the certificate issuers that you
    // want to trust. Can be a subset of the certificate issuers that are
    // trusted by the machine.
    //

    PWSTR pDefaultSslCtlIdentifier;

    //
    // Store name under LOCAL_MACHINE where Ctl identified by
    // pDefaultSslCtlIdentifier is stored.
    //

    PWSTR pDefaultSslCtlStoreName;

    //
    // Default Flags - see HTTP_SERVICE_CONFIG_SSL_FLAG* below.
    //

    DWORD DefaultFlags;

} HTTP_SERVICE_CONFIG_SSL_PARAM, *PHTTP_SERVICE_CONFIG_SSL_PARAM;

//
// The extended param type for the SSL extended params.
//

typedef enum _HTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE
{
    ExParamTypeHttp2Window,
    ExParamTypeHttp2SettingsLimits,
    ExParamTypeHttpPerformance,
    ExParamTypeTlsRestrictions,
    ExParamTypeErrorHeaders,
    ExParamTypeTlsSessionTicketKeys,
    ExParamTypeCertConfig,
    ExParamTypeMax
} HTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE, *PHTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE;

typedef struct _HTTP2_WINDOW_SIZE_PARAM
{
    //
    // The http/2 connection receive window size.
    //

    DWORD Http2ReceiveWindowSize;
} HTTP2_WINDOW_SIZE_PARAM, *PHTTP2_WINDOW_SIZE_PARAM;

typedef struct _HTTP2_SETTINGS_LIMITS_PARAM
{
    //
    // The maximum allowed settings per SETTINGS frame.
    //

    DWORD Http2MaxSettingsPerFrame;

    //
    // The maximum settings we will process in a minute.
    //

    DWORD Http2MaxSettingsPerMinute;
} HTTP2_SETTINGS_LIMITS_PARAM, *PHTTP2_SETTINGS_LIMITS_PARAM;

typedef enum _HTTP_PERFORMANCE_PARAM_TYPE
{
    PerformanceParamSendBufferingFlags,
    PerformanceParamAggressiveICW,
    PerformanceParamMaxSendBufferSize,
    PerformanceParamMaxConcurrentClientStreams,
    PerformanceParamMaxReceiveBufferSize,
    PerformanceParamDecryptOnSspiThread,
    PerformanceParamMax,
} HTTP_PERFORMANCE_PARAM_TYPE, *PHTTP_PERFORMANCE_PARAM_TYPE;

typedef struct _HTTP_PERFORMANCE_PARAM
{
    HTTP_PERFORMANCE_PARAM_TYPE Type;
    ULONG BufferSize;
    PVOID Buffer;
} HTTP_PERFORMANCE_PARAM, *PHTTP_PERFORMANCE_PARAM;

typedef struct _HTTP_TLS_RESTRICTIONS_PARAM
{
    ULONG RestrictionCount;
    PVOID TlsRestrictions;
} HTTP_TLS_RESTRICTIONS_PARAM, *PHTTP_TLS_RESTRICTIONS_PARAM;

typedef struct _HTTP_ERROR_HEADERS_PARAM
{
    USHORT StatusCode;
    USHORT HeaderCount;
    PHTTP_UNKNOWN_HEADER Headers;
} HTTP_ERROR_HEADERS_PARAM, *PHTTP_ERROR_HEADERS_PARAM;

typedef struct _HTTP_TLS_SESSION_TICKET_KEYS_PARAM
{
    ULONG SessionTicketKeyCount;
    PVOID SessionTicketKeys;
} HTTP_TLS_SESSION_TICKET_KEYS_PARAM, *PHTTP_TLS_SESSION_TICKET_KEYS_PARAM;

//
// This should really be defined by one of the security header files.
//

#define HTTP_SSL_CERT_SHA_HASH_LENGTH 20
#define HTTP_SSL_CERT_STORE_NAME_LENGTH 128

typedef struct _HTTP_CERT_CONFIG_ENTRY
{
    BYTE CertHash[HTTP_SSL_CERT_SHA_HASH_LENGTH];
    WCHAR CertStoreName[HTTP_SSL_CERT_STORE_NAME_LENGTH];
} HTTP_CERT_CONFIG_ENTRY, *PHTTP_CERT_CONFIG_ENTRY;

typedef struct _HTTP_CERT_CONFIG_PARAM
{
    ULONG CertConfigCount;
    PHTTP_CERT_CONFIG_ENTRY CertConfigs;
} HTTP_CERT_CONFIG_PARAM, *PHTTP_CERT_CONFIG_PARAM;

//
// This defines the extended params for the ssl config record.
//

typedef struct _HTTP_SERVICE_CONFIG_SSL_PARAM_EX
{
    //
    // The id that decides which param property is passed below.
    //

    HTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE ParamType;

    //
    // Flags for future use, if any.
    //

    ULONGLONG Flags;

    //
    // The property.
    //

    union
    {
        HTTP2_WINDOW_SIZE_PARAM Http2WindowSizeParam;
        HTTP2_SETTINGS_LIMITS_PARAM Http2SettingsLimitsParam;
        HTTP_PERFORMANCE_PARAM HttpPerformanceParam;
        HTTP_TLS_RESTRICTIONS_PARAM HttpTlsRestrictionsParam;
        HTTP_ERROR_HEADERS_PARAM HttpErrorHeadersParam;
        HTTP_TLS_SESSION_TICKET_KEYS_PARAM HttpTlsSessionTicketKeysParam;
        HTTP_CERT_CONFIG_PARAM HttpCertConfigParam;
    };
} HTTP_SERVICE_CONFIG_SSL_PARAM_EX, *PHTTP_SERVICE_CONFIG_SSL_PARAM_EX;

//
// The SSL config flags.
//

#define HTTP_SERVICE_CONFIG_SSL_FLAG_USE_DS_MAPPER              0x00000001
#define HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT      0x00000002
#if _WIN32_WINNT < 0x0600
#define HTTP_SERVICE_CONFIG_SSL_FLAG_NO_RAW_FILTER              0x00000004
#endif // _WIN32_WINNT < 0x0600
#define HTTP_SERVICE_CONFIG_SSL_FLAG_REJECT                     0x00000008

#define HTTP_SERVICE_CONFIG_SSL_FLAG_DISABLE_HTTP2              0x00000010
#define HTTP_SERVICE_CONFIG_SSL_FLAG_DISABLE_QUIC               0x00000020
#define HTTP_SERVICE_CONFIG_SSL_FLAG_DISABLE_TLS13              0x00000040

#define HTTP_SERVICE_CONFIG_SSL_FLAG_DISABLE_OCSP_STAPLING      0x00000080
#define HTTP_SERVICE_CONFIG_SSL_FLAG_ENABLE_TOKEN_BINDING       0x00000100
#define HTTP_SERVICE_CONFIG_SSL_FLAG_LOG_EXTENDED_EVENTS        0x00000200
#define HTTP_SERVICE_CONFIG_SSL_FLAG_DISABLE_LEGACY_TLS         0x00000400
#define HTTP_SERVICE_CONFIG_SSL_FLAG_ENABLE_SESSION_TICKET      0x00000800
#define HTTP_SERVICE_CONFIG_SSL_FLAG_DISABLE_TLS12              0x00001000
#define HTTP_SERVICE_CONFIG_SSL_FLAG_ENABLE_CLIENT_CORRELATION  0x00002000
#define HTTP_SERVICE_CONFIG_SSL_FLAG_DISABLE_SESSION_ID         0x00004000
#define HTTP_SERVICE_CONFIG_SSL_FLAG_ENABLE_CACHE_CLIENT_HELLO  0x00008000


//
// These data structures are used by HttpSetServiceConfiguration() to add a new
// record to the SSL bindings list.
//
// ConfigId                        | Structure
// --------------------------------+---------------------------------
// HttpServiceConfigSSLCertInfo    | HTTP_SERVICE_CONFIG_SSL_SET
// HttpServiceConfigSslSniCertInfo | HTTP_SERVICE_CONFIG_SSL_SNI_SET
// HttpServiceConfigSslCcsCertInfo | HTTP_SERVICE_CONFIG_SSL_CCS_SET
//

typedef struct _HTTP_SERVICE_CONFIG_SSL_SET
{
    HTTP_SERVICE_CONFIG_SSL_KEY     KeyDesc;
    HTTP_SERVICE_CONFIG_SSL_PARAM   ParamDesc;
} HTTP_SERVICE_CONFIG_SSL_SET, *PHTTP_SERVICE_CONFIG_SSL_SET;

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8

typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_SET
{
    HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc;
    HTTP_SERVICE_CONFIG_SSL_PARAM   ParamDesc;
} HTTP_SERVICE_CONFIG_SSL_SNI_SET, *PHTTP_SERVICE_CONFIG_SSL_SNI_SET;

typedef struct _HTTP_SERVICE_CONFIG_SSL_CCS_SET
{
    HTTP_SERVICE_CONFIG_SSL_CCS_KEY KeyDesc;
    HTTP_SERVICE_CONFIG_SSL_PARAM   ParamDesc;
} HTTP_SERVICE_CONFIG_SSL_CCS_SET, *PHTTP_SERVICE_CONFIG_SSL_CCS_SET;

typedef struct _HTTP_SERVICE_CONFIG_SSL_SET_EX
{
    HTTP_SERVICE_CONFIG_SSL_KEY_EX   KeyDesc;
    HTTP_SERVICE_CONFIG_SSL_PARAM_EX ParamDesc;
} HTTP_SERVICE_CONFIG_SSL_SET_EX, *PHTTP_SERVICE_CONFIG_SSL_SET_EX;

typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_SET_EX
{
    HTTP_SERVICE_CONFIG_SSL_SNI_KEY  KeyDesc;
    HTTP_SERVICE_CONFIG_SSL_PARAM_EX ParamDesc;
} HTTP_SERVICE_CONFIG_SSL_SNI_SET_EX, *PHTTP_SERVICE_CONFIG_SSL_SNI_SET_EX;

typedef struct _HTTP_SERVICE_CONFIG_SSL_CCS_SET_EX
{
    HTTP_SERVICE_CONFIG_SSL_CCS_KEY  KeyDesc;
    HTTP_SERVICE_CONFIG_SSL_PARAM_EX ParamDesc;
} HTTP_SERVICE_CONFIG_SSL_CCS_SET_EX, *PHTTP_SERVICE_CONFIG_SSL_CCS_SET_EX;

#endif

//
// These data structures are used by HttpQueryServiceConfiguration() to query a
// particular record from the SSL store.
//
// ConfigId                        | Structure
// --------------------------------+---------------------------------
// HttpServiceConfigSSLCertInfo    | HTTP_SERVICE_CONFIG_SSL_QUERY
// HttpServiceConfigSSLSniCertInfo | HTTP_SERVICE_CONFIG_SSL_SNI_QUERY
// HttpServiceConfigSslCcsCertInfo | HTTP_SERVICE_CONFIG_SSL_CCS_QUERY
//
// If QueryDesc is HttpServiceConfigQueryExact, then the one particular record
// is returned. If the QueryType is HttpServiceConfigQueryNext, then the next
// instance is returned. In such cases, the dwToken field represents the cursor.
// To retrieve the first item, dwToken has to be 0. For retrieving subsequent
// items, dwToken has to be incremented by 1, until ERROR_NO_MORE_ITEMS is
// returned.
//

typedef struct _HTTP_SERVICE_CONFIG_SSL_QUERY
{
    HTTP_SERVICE_CONFIG_QUERY_TYPE  QueryDesc;
    HTTP_SERVICE_CONFIG_SSL_KEY     KeyDesc;
    DWORD                           dwToken;
} HTTP_SERVICE_CONFIG_SSL_QUERY, *PHTTP_SERVICE_CONFIG_SSL_QUERY;

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8

typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_QUERY
{
    HTTP_SERVICE_CONFIG_QUERY_TYPE  QueryDesc;
    HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc;
    DWORD                           dwToken;
} HTTP_SERVICE_CONFIG_SSL_SNI_QUERY, *PHTTP_SERVICE_CONFIG_SSL_SNI_QUERY;

typedef struct _HTTP_SERVICE_CONFIG_SSL_CCS_QUERY
{
    HTTP_SERVICE_CONFIG_QUERY_TYPE  QueryDesc;
    HTTP_SERVICE_CONFIG_SSL_CCS_KEY KeyDesc;
    DWORD                           dwToken;
} HTTP_SERVICE_CONFIG_SSL_CCS_QUERY, *PHTTP_SERVICE_CONFIG_SSL_CCS_QUERY;

typedef struct _HTTP_SERVICE_CONFIG_SSL_QUERY_EX
{
    HTTP_SERVICE_CONFIG_QUERY_TYPE  QueryDesc;
    HTTP_SERVICE_CONFIG_SSL_KEY_EX  KeyDesc;
    DWORD                           dwToken;
    HTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE ParamType;
} HTTP_SERVICE_CONFIG_SSL_QUERY_EX, *PHTTP_SERVICE_CONFIG_SSL_QUERY_EX;

typedef struct _HTTP_SERVICE_CONFIG_SSL_SNI_QUERY_EX
{
    HTTP_SERVICE_CONFIG_QUERY_TYPE  QueryDesc;
    HTTP_SERVICE_CONFIG_SSL_SNI_KEY KeyDesc;
    DWORD                           dwToken;
    HTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE ParamType;
} HTTP_SERVICE_CONFIG_SSL_SNI_QUERY_EX, *PHTTP_SERVICE_CONFIG_SSL_SNI_QUERY_EX;

typedef struct _HTTP_SERVICE_CONFIG_SSL_CCS_QUERY_EX
{
    HTTP_SERVICE_CONFIG_QUERY_TYPE  QueryDesc;
    HTTP_SERVICE_CONFIG_SSL_CCS_KEY KeyDesc;
    DWORD                           dwToken;
    HTTP_SSL_SERVICE_CONFIG_EX_PARAM_TYPE ParamType;
} HTTP_SERVICE_CONFIG_SSL_CCS_QUERY_EX, *PHTTP_SERVICE_CONFIG_SSL_CCS_QUERY_EX;

#endif

//
// Set/Delete IP Listen-Only List record
//
// Used as a parameter to both HttpSetServiceConfiguration() and
// HttpDeleteServiceConfiguration() functions.
//

typedef struct _HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM
{
    USHORT      AddrLength;
    PSOCKADDR   pAddress;
} HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM, *PHTTP_SERVICE_CONFIG_IP_LISTEN_PARAM;

//
// Query IP Listen-Only List record.
//
// Parameter to HttpQueryServiceConfiguration() for the config ID
// HttpServiceConfigIPListenList.  On successful return, AddrList
// contains an array of AddrCount elements.  Caller must provide a
// large enough buffer to hold all elements in one call.
//
// Caller may determine the type of each returned element by examining
// AddrList[i].ss_family. If it's AF_INET, use ((PSOCKADDR_IN) &AddrList[i]);
// otherwise, for AF_INET6, use ((PSOCKADDR_IN6) &AddrList[i])
// to select the appropriate address type.
//

typedef struct _HTTP_SERVICE_CONFIG_IP_LISTEN_QUERY
{
    ULONG              AddrCount;
    SOCKADDR_STORAGE   AddrList[ANYSIZE_ARRAY];
} HTTP_SERVICE_CONFIG_IP_LISTEN_QUERY, *PHTTP_SERVICE_CONFIG_IP_LISTEN_QUERY;

//
// URL ACL
//
//
typedef struct _HTTP_SERVICE_CONFIG_URLACL_KEY
{
    PWSTR pUrlPrefix;

} HTTP_SERVICE_CONFIG_URLACL_KEY, *PHTTP_SERVICE_CONFIG_URLACL_KEY;

//
// This defines a record for the SSL config store.
//

typedef struct _HTTP_SERVICE_CONFIG_URLACL_PARAM
{
    PWSTR pStringSecurityDescriptor;
} HTTP_SERVICE_CONFIG_URLACL_PARAM, *PHTTP_SERVICE_CONFIG_URLACL_PARAM;


//
// This data structure is used by HttpSetServiceConfiguration for the config ID
// HttpServiceConfigUrlAclInfo. It is used to add a new record to the URL ACL
// store.
//

typedef struct _HTTP_SERVICE_CONFIG_URLACL_SET
{
    HTTP_SERVICE_CONFIG_URLACL_KEY   KeyDesc;
    HTTP_SERVICE_CONFIG_URLACL_PARAM ParamDesc;
} HTTP_SERVICE_CONFIG_URLACL_SET, *PHTTP_SERVICE_CONFIG_URLACL_SET;


//
// This data structure is used by HttpQueryServiceConfiguration() for the
// config ID HttpServiceConfigUrlAclInfo. It's used to query a particular
// record from the URL ACL store.
//
// If QueryType is HttpServiceConfigQueryExact, then one particular record of
// the type HTTP_SERVICE_CONFIG_URLACL_SET is returned. If the QueryType is
// HttpServiceConfigQueryNext, then the next instance of
// HTTP_SERVICE_CONFIG_URLACL_SET is returned. In such cases, the dwToken field
// represents the cursor. For the first item,  dwToken has to be 0.
// For subsequent items, dwToken has to be incremented by 1,
// until ERROR_NO_MORE_ITEMS is returned.
//

typedef struct _HTTP_SERVICE_CONFIG_URLACL_QUERY
{
    HTTP_SERVICE_CONFIG_QUERY_TYPE  QueryDesc;
    HTTP_SERVICE_CONFIG_URLACL_KEY  KeyDesc;
    DWORD                           dwToken;
} HTTP_SERVICE_CONFIG_URLACL_QUERY, *PHTTP_SERVICE_CONFIG_URLACL_QUERY;

//
// Cache Paramemers
//

//
// For manipulating global cache parameters.
// The parameters that can be changed or queued are per-uri cache size
// and cached range chunk size.
//

typedef enum _HTTP_SERVICE_CONFIG_CACHE_KEY
{
    MaxCacheResponseSize = 0,
    CacheRangeChunkSize
} HTTP_SERVICE_CONFIG_CACHE_KEY, *PHTTP_SERVICE_CONFIG_CACHE_KEY;

typedef ULONG HTTP_SERVICE_CONFIG_CACHE_PARAM,
    *PHTTP_SERVICE_CONFIG_CACHE_PARAM;

//
// To set a cache parameter value use the set structure. To query use the key
// directly. When you query a parameter value the output buffer must be exactly
// the sizeof param.
//

typedef struct {
    HTTP_SERVICE_CONFIG_CACHE_KEY       KeyDesc;
    HTTP_SERVICE_CONFIG_CACHE_PARAM     ParamDesc;
} HTTP_SERVICE_CONFIG_CACHE_SET, *PHTTP_SERVICE_CONFIG_CACHE_SET;

//
// Input types for HttpQueryRequestProperty. Only types are public and not the API
// so that IIS need not have their own types for public usage.
//

typedef enum _HTTP_REQUEST_PROPERTY
{
    HttpRequestPropertyIsb,
    HttpRequestPropertyTcpInfoV0,
    HttpRequestPropertyQuicStats,
    HttpRequestPropertyTcpInfoV1,
    HttpRequestPropertySni,
    HttpRequestPropertyStreamError,
    HttpRequestPropertyWskApiTimings,
    HttpRequestPropertyQuicApiTimings,
    HttpRequestPropertyQuicStatsV2,
    HttpRequestPropertyQuicStreamStats,
    HttpRequestPropertyTcpInfoV2,
    HttpRequestPropertyTlsClientHello,
    HttpRequestPropertyTransportIdleConnectionTimeout,
    HttpRequestPropertyDscpTag,
    HttpRequestPropertyTlsCipherInfo,
} HTTP_REQUEST_PROPERTY, *PHTTP_REQUEST_PROPERTY;

typedef struct _HTTP_QUERY_REQUEST_QUALIFIER_TCP
{
    ULONGLONG Freshness;
} HTTP_QUERY_REQUEST_QUALIFIER_TCP, *PHTTP_QUERY_REQUEST_QUALIFIER_TCP;

typedef struct _HTTP_QUERY_REQUEST_QUALIFIER_QUIC
{
    ULONGLONG Freshness;
} HTTP_QUERY_REQUEST_QUALIFIER_QUIC, *PHTTP_QUERY_REQUEST_QUALIFIER_QUIC;

#define HTTP_REQUEST_PROPERTY_SNI_HOST_MAX_LENGTH 255

//
// Flags inside HTTP_REQUEST_PROPERTY_SNI can have following values:
// - HTTP_REQUEST_PROPERTY_SNI_FLAG_SNI_USED: Indicates that SNI was used for succesful
//   endpoint lookup during handshake. If client sent the SNI but Http.sys still decided to
//   use IP endpoint binding then this flag will not be set.
// - HTTP_REQUEST_PROPERTY_SNI_FLAG_NO_SNI: Indicates that client did not send the SNI.
//   If this flag is set, HTTP_REQUEST_PROPERTY_SNI_FLAG_SNI_USED can not be set.
//

#define HTTP_REQUEST_PROPERTY_SNI_FLAG_SNI_USED 0x00000001
#define HTTP_REQUEST_PROPERTY_SNI_FLAG_NO_SNI   0x00000002

typedef struct _HTTP_REQUEST_PROPERTY_SNI
{
    WCHAR Hostname[HTTP_REQUEST_PROPERTY_SNI_HOST_MAX_LENGTH + 1];
    ULONG Flags;
} HTTP_REQUEST_PROPERTY_SNI, *PHTTP_REQUEST_PROPERTY_SNI;

typedef struct _HTTP_REQUEST_PROPERTY_STREAM_ERROR
{
    ULONG ErrorCode;
} HTTP_REQUEST_PROPERTY_STREAM_ERROR, *PHTTP_REQUEST_PROPERTY_STREAM_ERROR;

typedef struct _HTTP_WSK_API_TIMINGS
{
    ULONGLONG ConnectCount;
    ULONGLONG ConnectSum;
    ULONGLONG DisconnectCount;
    ULONGLONG DisconnectSum;

    ULONGLONG SendCount;
    ULONGLONG SendSum;
    ULONGLONG ReceiveCount;
    ULONGLONG ReceiveSum;

    ULONGLONG ReleaseCount;
    ULONGLONG ReleaseSum;

    ULONGLONG ControlSocketCount;
    ULONGLONG ControlSocketSum;
} HTTP_WSK_API_TIMINGS, *PHTTP_WSK_API_TIMINGS;

typedef struct _HTTP_QUIC_STREAM_API_TIMINGS
{
    ULONGLONG OpenCount;
    ULONGLONG OpenSum;
    ULONGLONG CloseCount;
    ULONGLONG CloseSum;

    ULONGLONG StartCount;
    ULONGLONG StartSum;
    ULONGLONG ShutdownCount;
    ULONGLONG ShutdownSum;

    ULONGLONG SendCount;
    ULONGLONG SendSum;

    ULONGLONG ReceiveSetEnabledCount;
    ULONGLONG ReceiveSetEnabledSum;

    ULONGLONG GetParamCount;
    ULONGLONG GetParamSum;

    ULONGLONG SetParamCount;
    ULONGLONG SetParamSum;

    ULONGLONG SetCallbackHandlerCount;
    ULONGLONG SetCallbackHandlerSum;

} HTTP_QUIC_STREAM_API_TIMINGS, *PHTTP_QUIC_STREAM_API_TIMINGS;

typedef struct _HTTP_QUIC_CONNECTION_API_TIMINGS
{
    ULONGLONG OpenTime;
    ULONGLONG CloseTime;

    ULONGLONG StartTime;
    ULONGLONG ShutdownTime;

    ULONGLONG SecConfigCreateTime;
    ULONGLONG SecConfigDeleteTime;

    ULONGLONG GetParamCount;
    ULONGLONG GetParamSum;

    ULONGLONG SetParamCount;
    ULONGLONG SetParamSum;

    ULONGLONG SetCallbackHandlerCount;
    ULONGLONG SetCallbackHandlerSum;

    HTTP_QUIC_STREAM_API_TIMINGS ControlStreamTimings;

} HTTP_QUIC_CONNECTION_API_TIMINGS, *PHTTP_QUIC_CONNECTION_API_TIMINGS;

typedef struct _HTTP_QUIC_API_TIMINGS
{
    HTTP_QUIC_CONNECTION_API_TIMINGS ConnectionTimings;
    HTTP_QUIC_STREAM_API_TIMINGS StreamTimings;

} HTTP_QUIC_API_TIMINGS, *PHTTP_QUIC_API_TIMINGS;

typedef struct _HTTP_QUIC_STREAM_REQUEST_STATS
{
    ULONGLONG StreamWaitStart;
    ULONGLONG StreamWaitEnd;

    ULONGLONG RequestHeadersCompressionStart;
    ULONGLONG RequestHeadersCompressionEnd;

    ULONGLONG ResponseHeadersDecompressionStart;
    ULONGLONG ResponseHeadersDecompressionEnd;

    ULONGLONG RequestHeadersCompressedSize;
    ULONGLONG ResponseHeadersCompressedSize;

} HTTP_QUIC_STREAM_REQUEST_STATS, *PHTTP_QUIC_STREAM_REQUEST_STATS;

#define HTTP_QUIC_KEEPALIVE_TIMEOUT_DISABLED ((ULONG)-1)

typedef enum _HTTP_FEATURE_ID
{
    HttpFeatureUnknown                              = 0,
    HttpFeatureResponseTrailers                     = 1,
    HttpFeatureApiTimings                           = 2,
    HttpFeatureDelegateEx                           = 3,
    HttpFeatureHttp3                                = 4,
    HttpFeatureTlsSessionTickets                    = 5,
    HttpFeatureDisableTlsSessionId                  = 6,
    HttpFeatureTlsDualCerts                         = 7,
    HttpFeatureAutomaticChunkedEncoding             = 8,
    HttpFeatureDedicatedReqQueueDelegationType      = 9,
    HttpFeatureFastForwardResponse                  = 10,
    HttpFeatureCacheTlsClientHello                  = 11,
    HttpFeatureIdleConnectionTimeoutRequestProperty = 12,
    HttpFeatureDisableAiaFlag                       = 13,
    HttpFeatureDscp                                 = 14,
    HttpFeatureQueryCipherInfo                      = 15,
    HttpFeatureQueryInitialPacketTtl                = 16,
    HttpFeatureLast                                 = 17,


    HttpFeaturemax              = 0xFFFFFFFF,

} HTTP_FEATURE_ID, *PHTTP_FEATURE_ID;


//
// Define our API linkage.
//

#if !defined(HTTPAPI_LINKAGE)
#define HTTPAPI_LINKAGE DECLSPEC_IMPORT
#endif  // !HTTPAPI_LINKAGE

//
// Initialize/Terminate APIs.
//


// NOTE: MUST be called once before all other APIs

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpInitialize(
    IN HTTPAPI_VERSION Version,
    IN ULONG Flags,
    _Reserved_ IN OUT PVOID pReserved
    );

// NOTE: MUST be called after final API call returns.

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpTerminate(
    IN ULONG Flags,
    _Reserved_ IN OUT PVOID pReserved
    );

//
// HTTP Request Queue manipulation APIs.
//
// This API is maintained for backward competibility for the first
// version of the HTTPAPI and should not be used. Instead the new
// HttpCreateRequestQueue() API must be used.
//
// Use CloseHandle() to release the handles returned by
// HttpCreateHttpHandle() API.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCreateHttpHandle(
    OUT PHANDLE RequestQueueHandle,
    _Reserved_ ULONG Reserved
    );

#if _WIN32_WINNT >= 0x0600

//
// Extended Request Queue manipulation APIs.
//
// Use HttpCloseRequestQueue() API to close the handles
// created by the HttpCreateRequestQueue API.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCreateRequestQueue(
    IN HTTPAPI_VERSION Version,
    IN PCWSTR Name OPTIONAL,
    IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL,
    IN ULONG Flags OPTIONAL,
    OUT PHANDLE RequestQueueHandle
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCloseRequestQueue(
    IN HANDLE RequestQueueHandle
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSetRequestQueueProperty(
    _In_ HANDLE RequestQueueHandle,
    _In_ HTTP_SERVER_PROPERTY Property,
    _In_reads_bytes_(PropertyInformationLength) PVOID PropertyInformation,
    _In_ ULONG PropertyInformationLength,
    _Reserved_ ULONG Reserved1,
    _Reserved_ PVOID Reserved2
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpQueryRequestQueueProperty(
    _In_ HANDLE RequestQueueHandle,
    _In_ HTTP_SERVER_PROPERTY Property,
    _Out_writes_bytes_to_opt_(PropertyInformationLength, *ReturnLength) PVOID PropertyInformation,
    _In_ ULONG PropertyInformationLength,
    _Reserved_ ULONG Reserved1,
    _Out_opt_ PULONG ReturnLength,
    _Reserved_ PVOID Reserved2
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSetRequestProperty(
    _In_ HANDLE RequestQueueHandle,
    _In_ HTTP_OPAQUE_ID Id,
    _In_ HTTP_REQUEST_PROPERTY PropertyId,
    _In_reads_bytes_opt_(InputPropertySize) PVOID Input,
    _In_ ULONG InputPropertySize,
    _In_ LPOVERLAPPED Overlapped
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpQueryRequestProperty(
    _In_ HANDLE RequestQueueHandle,
    _In_ HTTP_OPAQUE_ID Id,
    _In_ HTTP_REQUEST_PROPERTY PropertyId,
    _In_reads_bytes_opt_(QualifierSize) const VOID *Qualifier,
    _In_ ULONG QualifierSize,
    _Out_writes_bytes_to_opt_(OutputBufferSize, *BytesReturned) PVOID Output,
    _In_ ULONG OutputBufferSize,
    _Out_opt_ PULONG BytesReturned,
    _In_opt_ LPOVERLAPPED Overlapped
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpShutdownRequestQueue(
    IN HANDLE RequestQueueHandle
    );

#endif // _WIN32_WINNT >= 0x0600

//
// SSL APIs.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpReceiveClientCertificate(
    IN HANDLE RequestQueueHandle,
    IN HTTP_CONNECTION_ID ConnectionId,
    IN ULONG Flags,
    _Out_writes_bytes_to_(SslClientCertInfoSize, *BytesReceived) PHTTP_SSL_CLIENT_CERT_INFO SslClientCertInfo,
    IN ULONG SslClientCertInfoSize,
    _Out_opt_ PULONG BytesReceived,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

#if _WIN32_WINNT >= 0x0600

//
// Server Session APIs.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCreateServerSession(
    IN HTTPAPI_VERSION Version,
    OUT PHTTP_SERVER_SESSION_ID ServerSessionId,
    _Reserved_ IN ULONG Reserved
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCloseServerSession(
    IN HTTP_SERVER_SESSION_ID ServerSessionId
    );

HTTPAPI_LINKAGE
_Success_(return == NO_ERROR)
ULONG
WINAPI
HttpQueryServerSessionProperty(
    IN HTTP_SERVER_SESSION_ID ServerSessionId,
    IN HTTP_SERVER_PROPERTY Property,
    _Out_writes_bytes_to_opt_(PropertyInformationLength, *ReturnLength) PVOID PropertyInformation,
    IN ULONG PropertyInformationLength,
    _Out_opt_ PULONG ReturnLength
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSetServerSessionProperty(
    IN HTTP_SERVER_SESSION_ID ServerSessionId,
    IN HTTP_SERVER_PROPERTY Property,
    _In_reads_bytes_(PropertyInformationLength) PVOID PropertyInformation,
    IN ULONG PropertyInformationLength
    );

#endif // _WIN32_WINNT >= 0x0600

//
// Url Configuration APIs. Can only be used for V1 request queues.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpAddUrl(
    IN HANDLE RequestQueueHandle,
    IN PCWSTR FullyQualifiedUrl,
    _Reserved_ PVOID Reserved
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpRemoveUrl(
    IN HANDLE RequestQueueHandle,
    IN PCWSTR FullyQualifiedUrl
    );

#if _WIN32_WINNT >= 0x0600

//
// Url Group APIs.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCreateUrlGroup(
    IN HTTP_SERVER_SESSION_ID ServerSessionId,
    OUT PHTTP_URL_GROUP_ID pUrlGroupId,
    _Reserved_ IN ULONG Reserved
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCloseUrlGroup(
    IN HTTP_URL_GROUP_ID UrlGroupId
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpAddUrlToUrlGroup(
    IN HTTP_URL_GROUP_ID UrlGroupId,
    IN PCWSTR pFullyQualifiedUrl,
    IN HTTP_URL_CONTEXT UrlContext OPTIONAL,
    _Reserved_ IN ULONG Reserved
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpRemoveUrlFromUrlGroup(
    IN HTTP_URL_GROUP_ID UrlGroupId,
    IN PCWSTR pFullyQualifiedUrl,
    IN ULONG Flags
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSetUrlGroupProperty(
    IN HTTP_URL_GROUP_ID UrlGroupId,
    IN HTTP_SERVER_PROPERTY Property,
    _In_reads_bytes_(PropertyInformationLength) PVOID PropertyInformation,
    IN ULONG PropertyInformationLength
    );

HTTPAPI_LINKAGE
_Success_(return == NO_ERROR)
ULONG
WINAPI
HttpQueryUrlGroupProperty(
    IN HTTP_URL_GROUP_ID UrlGroupId,
    IN HTTP_SERVER_PROPERTY Property,
    _Out_writes_bytes_to_opt_(PropertyInformationLength, *ReturnLength) PVOID PropertyInformation,
    IN ULONG PropertyInformationLength,
    _Out_opt_ PULONG ReturnLength
    );

#endif // _WIN32_WINNT >= 0x0600

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpPrepareUrl(
    _Reserved_ PVOID Reserved,
    _Reserved_ ULONG Flags,
    _In_ PCWSTR Url,
    _Outptr_ PWSTR *PreparedUrl
    );

#endif

//
// HTTP Server I/O APIs.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpReceiveHttpRequest(
    IN HANDLE RequestQueueHandle,
    IN HTTP_REQUEST_ID RequestId,
    IN ULONG Flags,
    _Out_writes_bytes_to_(RequestBufferLength, *BytesReturned) PHTTP_REQUEST RequestBuffer,
    IN ULONG RequestBufferLength,
    _Out_opt_ PULONG BytesReturned,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpReceiveRequestEntityBody(
    IN HANDLE RequestQueueHandle,
    IN HTTP_REQUEST_ID RequestId,
    IN ULONG Flags,
    _Out_writes_bytes_to_(EntityBufferLength, *BytesReturned) PVOID EntityBuffer,
    IN ULONG EntityBufferLength,
    _Out_opt_ PULONG BytesReturned,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

#if _WIN32_WINNT >= 0x0600

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSendHttpResponse(
    IN HANDLE RequestQueueHandle,
    IN HTTP_REQUEST_ID RequestId,
    IN ULONG Flags,
    IN PHTTP_RESPONSE HttpResponse,
    IN PHTTP_CACHE_POLICY CachePolicy OPTIONAL,
    OUT PULONG BytesSent OPTIONAL,
    _Reserved_ PVOID Reserved1,
    _Reserved_ ULONG Reserved2,
    IN LPOVERLAPPED Overlapped OPTIONAL,
    IN PHTTP_LOG_DATA LogData OPTIONAL
    );

#else // _WIN32_WINNT >= 0x0600

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSendHttpResponse(
    IN HANDLE ReqQueueHandle,
    IN HTTP_REQUEST_ID RequestId,
    IN ULONG Flags,
    IN PHTTP_RESPONSE pHttpResponse,
    IN PVOID pReserved1 OPTIONAL, // must be NULL
    OUT PULONG pBytesSent OPTIONAL,
    _Reserved_ PVOID pReserved2, // must be NULL
    _Reserved_ ULONG Reserved3, // must be 0
    IN LPOVERLAPPED pOverlapped OPTIONAL,
    IN PVOID pReserved4 OPTIONAL  // must be NULL
    );

#endif // _WIN32_WINNT >= 0x0600

#if _WIN32_WINNT >= 0x0600

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSendResponseEntityBody(
    IN HANDLE RequestQueueHandle,
    IN HTTP_REQUEST_ID RequestId,
    IN ULONG Flags,
    IN USHORT EntityChunkCount OPTIONAL,
    _In_reads_opt_(EntityChunkCount) PHTTP_DATA_CHUNK EntityChunks,
    OUT PULONG BytesSent OPTIONAL,
    _Reserved_ PVOID Reserved1 OPTIONAL,
    _Reserved_ ULONG Reserved2 OPTIONAL,
    IN LPOVERLAPPED Overlapped OPTIONAL,
    IN PHTTP_LOG_DATA LogData OPTIONAL
    );

#else // _WIN32_WINNT >= 0x0600

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSendResponseEntityBody(
    IN HANDLE ReqQueueHandle,
    IN HTTP_REQUEST_ID RequestId,
    IN ULONG Flags,
    IN USHORT EntityChunkCount OPTIONAL,
    _In_reads_opt_(EntityChunkCount)
    IN PHTTP_DATA_CHUNK pEntityChunks OPTIONAL,
    OUT PULONG pBytesSent OPTIONAL,
    _Reserved_ PVOID pReserved1 OPTIONAL, // must be NULL
    _Reserved_ ULONG Reserved2 OPTIONAL, // must be 0
    IN LPOVERLAPPED pOverlapped OPTIONAL,
    IN PVOID pReserved3 OPTIONAL  // must be NULL
    );

#endif // _WIN32_WINNT >= 0x0600

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpDeclarePush(
    _In_ HANDLE RequestQueueHandle,
    _In_ HTTP_REQUEST_ID RequestId,
    _In_ HTTP_VERB Verb,
    _In_ PCWSTR Path,
    _In_opt_ PCSTR Query,
    _In_opt_ PHTTP_REQUEST_HEADERS Headers
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpWaitForDisconnect(
    IN HANDLE RequestQueueHandle,
    IN HTTP_CONNECTION_ID ConnectionId,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

#if _WIN32_WINNT >= 0x0600

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpWaitForDisconnectEx(
    IN HANDLE RequestQueueHandle,
    IN HTTP_CONNECTION_ID ConnectionId,
    _Reserved_ IN ULONG Reserved OPTIONAL,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpCancelHttpRequest(
    IN HANDLE RequestQueueHandle,
    IN HTTP_REQUEST_ID RequestId,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpWaitForDemandStart(
    IN HANDLE RequestQueueHandle,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

BOOL
WINAPI
HttpIsFeatureSupported(
    _In_ HTTP_FEATURE_ID FeatureId
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpDelegateRequestEx(
    _In_ HANDLE RequestQueueHandle,
    _In_ HANDLE DelegateQueueHandle,
    _In_ HTTP_REQUEST_ID RequestId,
    _In_ HTTP_URL_GROUP_ID DelegateUrlGroupId,
    _In_ ULONG PropertyInfoSetSize,
    _In_ PHTTP_DELEGATE_REQUEST_PROPERTY_INFO PropertyInfoSet
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpFindUrlGroupId(
    _In_ PCWSTR FullyQualifiedUrl,
    _In_ HANDLE RequestQueueHandle,
    _Out_ PHTTP_URL_GROUP_ID UrlGroupId
    );


#endif // _WIN32_WINNT >= 0x0600

//
// Cache manipulation APIs.
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpFlushResponseCache(
    IN HANDLE RequestQueueHandle,
    IN PCWSTR UrlPrefix,
    IN ULONG Flags,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpAddFragmentToCache(
    IN HANDLE RequestQueueHandle,
    IN PCWSTR UrlPrefix,
    IN PHTTP_DATA_CHUNK DataChunk,
    IN PHTTP_CACHE_POLICY CachePolicy,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpReadFragmentFromCache(
    IN HANDLE RequestQueueHandle,
    IN PCWSTR UrlPrefix,
    IN PHTTP_BYTE_RANGE ByteRange OPTIONAL,
    _Out_writes_bytes_to_(BufferLength, *BytesRead) PVOID Buffer,
    IN ULONG BufferLength,
    _Out_opt_ PULONG BytesRead,
    IN LPOVERLAPPED Overlapped OPTIONAL
    );

//
// Server configuration APIs
//

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpSetServiceConfiguration(
    _Reserved_ HANDLE ServiceHandle,
    _In_ HTTP_SERVICE_CONFIG_ID ConfigId,
    _In_reads_bytes_(ConfigInformationLength) PVOID pConfigInformation,
    _In_ ULONG ConfigInformationLength,
    _Reserved_ LPOVERLAPPED pOverlapped
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpUpdateServiceConfiguration(
    _Reserved_ HANDLE Handle,
    _In_ HTTP_SERVICE_CONFIG_ID ConfigId,
    _In_reads_bytes_(ConfigInfoLength) PVOID ConfigInfo,
    _In_ ULONG ConfigInfoLength,
    _Reserved_ LPOVERLAPPED Overlapped
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpDeleteServiceConfiguration(
    _Reserved_ HANDLE ServiceHandle,
    _In_ HTTP_SERVICE_CONFIG_ID ConfigId,
    _In_reads_bytes_(ConfigInformationLength) PVOID pConfigInformation,
    _In_ ULONG ConfigInformationLength,
    _Reserved_ LPOVERLAPPED pOverlapped
    );

HTTPAPI_LINKAGE
ULONG
WINAPI
HttpQueryServiceConfiguration(
    _Reserved_ HANDLE ServiceHandle,
    _In_ HTTP_SERVICE_CONFIG_ID ConfigId,
    _In_reads_bytes_opt_(InputLength) PVOID pInput,
    _In_ ULONG InputLength,
    _Out_writes_bytes_to_opt_(OutputLength, *pReturnLength) PVOID pOutput,
    _In_ ULONG OutputLength,
    _Out_opt_ PULONG pReturnLength,
    _Reserved_ LPOVERLAPPED pOverlapped
    );

ULONG
WINAPI
HttpGetExtension(
    __in HTTPAPI_VERSION Version,
    __in ULONG Extension,
    __out PVOID __bcount(BufferSize) Buffer,
    __in ULONG BufferSize
    );


#ifdef __cplusplus
}   // extern "C"
#endif  // __cplusplus

#endif // _WIN32_WINNT >= 0x0501


#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion

#endif // __HTTP_H__

